2009-11-29 4 views
2

Мне просто нужно подтверждение, что я правильно понял концепцию блокировок в синхронизированных блоках. Сначала я расскажу, что я понял. Приобретение блокировки объекта означает, что ни один другой поток не может получить доступ к синхронизированному коду класса объекта. В случае синхронизированных методов потоки приобретают блокировку для объекта, используемого для вызова метода (т. Е. Неявно эта ссылка). Это означает, что другие потоки не могут получить доступ к синхронизированному коду класса текущего объекта. Но в случае синхронизированных блоков мы можем указать объект, по которому мы хотим, чтобы поток приобрел блокировку.Замки в синхронизированных блоках

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

Если какой-либо другой поток использует тот же объект класса B, он не сможет ввести синхронизированный блок в классе A, правильно? А также другие потоки не могут также получить доступ к любому синхронизированному коду в классе B?

А как насчет другого синхронизированного кода в классе A? Поскольку поток приобрел блокировку объекта класса B, другие потоки могут получить доступ к другому синхронизированному коду класса A или нет? Это означает, что на объекте класса А нет блокировки только класса B?

Надеюсь, люди поймут мои вопросы.

Заранее спасибо.

+1

Классы не имеют отношения к классам (за исключением того, что, к сожалению, статические методы, помеченные как синхронизированная блокировка объекта 'Class' - D'oh). Подумайте о блокировках как о другом объекте, который каждый объект несет вокруг окончательной ссылки (это плохой дизайн!), Блокировка объекта не означает, что код, который не беспокоит блокировку, не может получить доступ к полям объекта. –

ответ

1

Во-первых, я думаю, вам лучше отвлечь слово из разговоров. Предположим, что у вас есть два объекта o1 и o2, которые являются экземплярами классов, которые фактически не имеют отношения к обсуждению, и что o1 имеет ссылку на o2.

Если o1 синхронизирует блок на примере o2, то ни один другой поток не может войти в синхронизированный раздел в том же экземпляре o2. Это может быть либо нестатический синхронизированный метод o2, либо любой синхронизированный блок, который запрашивает блокировку на одном и том же объекте (предположим, что есть объект o3, который также имеет ссылку на o2 и хочет синхронизировать его, он будет заблокирован до o1 освобождает замок).

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

public synchronized void synch1() { 
    // body 
} 
// equivalent to: 
public void synch2() { 
    synchronized(this) { 
     // body 
    } 
} 

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

2

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

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

Теперь, если вы говорите о синхронизирована (не статический) метод, то объект, который будет заблокирован является this для вызываемого метода. Но применяются те же правила.

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

Если какой-либо другой поток использует тот же самый объект класса B не сможет войти в синхронизированный блок в класса А, верно? А также другие потоки также не могут получить доступ к любому синхронизированному коду в классе B?

Первая часть правильная, если «другой поток» синхронизируется в одном экземпляре B. В противном случае это неверно.

Вторая часть неверна. Это только код, который синхронизируется в том же экземпляре B, который заблокирован.

+0

«Это только код, который синхронизируется в одном экземпляре B, который заблокирован». Значит, вы имеете в виду, что код в классе A, синхронизированный на объекте класса B, будет заблокирован. И если у класса B есть синхронизированный код, он не будет заблокирован? У меня есть этот вопрос, потому что это блокировка объекта класса B, которую мы приобретаем. Эта блокировка также должна блокировать синхронизированный код в calss B. Не так ли? – TheCoolestSid

+1

Нет. Я имею в виду, что он будет заблокирован только в том случае, если он синхронизируется с одним и тем же объектом B. Дело в том, что расположение кода не имеет значения; * Единственное, что имеет значение *, - это объект, который вы синхронизируете. –

+0

Хорошо. Поэтому, если поток приобрел блокировку на объекте, весь код, синхронизированный на этом объекте, будет заблокирован любым, где может быть код. – TheCoolestSid

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