2010-07-29 4 views
11

Когда мы говорим о встроенной блокировке, мы ссылаемся на объект, для которого мы запрашиваем блокировку или для синхронизированного метода?резьба встроенного замка

Замок находится на объекте или на его методе синхронизации?

Я смущен!

ответ

4

Синхронизированных методы блокирует метод объекта

synchronized void methodA() { 
    ....  
} 

какой-то образом эквивалентен

void methodA() { 
    synchronized (this) { 
     .... 
    } 
} 
+0

Каждый объект имеет встроенный замок. Эти два утверждения эквивалентны, поскольку оба они синхронизируются по внутренней блокировке объекта, содержащего метод A(). – Brandon

+0

Объяснение Синхронизированные утверждения для человека, который не понимает Синхронизированные методы - это не очень хорошая идея. Это только смутило меня еще больше. –

15

характеристических замков на объекте:

class A 
{ 
    public synchronized void method1(){...} 
    public synchronized void method2(){...} 
} 

Если поток А находится в method1 то threadB не может ввести метод2.

+1

Желаю, Stackoverflow позволяет мне +10 для вашей последней строки. :) – UnKnown

1

Замок является частью объекта. Каждый объект имеет один, и это может быть заблокированы два способов:

  1. Использования synchronized модификатора метода экземпляра класса для блокировки связанного объекта
  2. Использования synchronized(object) {} блока

Аналогично, вы можете заблокировать класс объекта, а не сам объект (указывается отдельно для понимания модификатора synchronized с использованием метода static):

  1. Использование synchronized модификатора на статический метод класса для блокировки класса
  2. Использование synchronized(clazz) {} блок, где clazz является класс объекта
0

Замок находится на объекте. В Java каждый объект является monitor

9

В Java, внутренняя блокировка подразумеваются каждым использование синхронизированного ключевого слова

Каждого использование синхронизированного ключевым слова, связанные с одним из двух типов внутренней блокировки:

«экземпляр замок», прикрепленный к одному объекту

«статический замок», прикрепленный к классу

Если метод объявлен как синхронизировано, то она будет приобретать либо блокировку экземпляра или статической блокировки при ее вызове, в зависимости от того, является ли это методом экземпляра или статическим методом.

Эти два типа замков имеют сходное поведение, но полностью независимы друг от друга.

Приобретение блокировки экземпляра блокирует другие потоки только от вызова метода синхронизированного экземпляра; он не блокирует другие потоки от вызова несинхронизированного метода и не блокирует их от вызова статического синхронизированного метода.

Аналогичным образом, приобретение статического замка блокирует другие потоки только от вызова статического синхронизированного метода; он не блокирует другие потоки от вызова несинхронизированного метода и не блокирует их от вызова метода синхронизированного экземпляра.

Вне заголовка метода, синхронизированный (этот) получает блокировку экземпляра.

Статический замок может быть получен за пределами заголовка метода двумя способами:

синхронизированы (Blah.class), используя класс буквального

синхронизированы (this.getClass()), если объект

0
private int count = 0; 
public synchronized void countFunc(){ 
     count++; 
    } 
Thread t1 = new Thread(new Runnable(){ 
      public void run(){ 
      for(int i=0;i<1000;i++){ 
       countFunc(); 
       }}}); 
     Thread t2 = new Thread(new Runnable(){ 
      public void run(){ 
      for(int i=0;i<1000;i++){ 
       countFunc(); 
      }}}); 

В приведенном выше примере у меня есть 2 потока, пытающихся увеличить значение count. И чтобы предотвратить чередование нитей, я пытаюсь захватить внутреннюю блокировку с помощью synchronized ключевое слово.

Окончательно, В этом примере замокявляется блок методом countFunc с синхронизированы ключевого слова и замокявляетсянасчетчик переменной. Надеюсь, что это поможет

0

Замок находится на объекте.

Посмотрите на страницу учебник Java на intrinsic locks

Каждый объект имеет внутреннюю блокировку, связанную с ним. По соглашению поток, который нуждается в эксклюзивном и последовательном доступе к полям объекта, должен получить внутреннюю блокировку объекта перед тем, как получить доступ к ним, а затем освободить внутреннюю блокировку, когда это будет сделано с ними. Говорят, что поток имеет собственный замок между временем, когда он приобрел замок, и освободил замок.

Пока нить владеет встроенным замком, ни одна другая нить не может получить тот же замок. Другой поток будет блокироваться, когда он попытается получить блокировку.

Два способа использования внутренних замков:

  1. Синхронных методы:

    Когда поток вызывает метод synchronized, он автоматически приобретает внутренней блокировки для объекта этого метода и освобождает его при возврате метода.

    например.

    public synchronized void incrementCounter(){ 
        ++counter; 
    } 
    
  2. Синхронные заявления

    В отличие от synchronized методов, synchronized заявления необходимо указать объект, который обеспечивает Характеристическая Заблокируйте

    public int getCounter(){ 
        synchronized(this){ 
         return counter; 
        } 
    } 
    

    Полный пример:

    public class SynchronizedDemo{ 
    private int counter = 0; 
    
    public SynchronizedDemo(){ 
    
    } 
    public synchronized void incrementCounter(){ 
        ++counter; 
    } 
    public int getCounter(){ 
        synchronized(this){ 
         return counter; 
        } 
    } 
    public static void main(String[] args){ 
        SynchronizedDemo object = new SynchronizedDemo(); 
        for (int i=0; i < 5; i++){ 
         Thread t = new Thread(new SimpleRunnable(object)); 
         t.start(); 
        }   
    } 
    } 
    class SimpleRunnable implements Runnable{ 
    private SynchronizedDemo object; 
    
    public SimpleRunnable(SynchronizedDemo obj){ 
        this.object = obj; 
    } 
    public void run(){ 
        object.incrementCounter(); 
        System.out.println("Counter:"+object.getCounter()); 
    } 
    } 
    

Примечание: Этого пример написан только для демонстрации различных способов использования внутренних замков. Использование AtomicInteger для переменной счетчика является правильным подходом для этого типа прецедента.

Смежные вопросы