Размер шрифта
-
+

Многопоточное программирование в Java - стр. 5

Освобождение блокировки происходит, даже если возврат метода был вызван неперехваченным исключением.

Другими словами, каждый объект в Java имеет ассоциированный с ним монитор.

Монитор представляет своего рода инструмент для управления доступа к объекту.

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

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

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

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

Конструкторы не могут быть синхронизированы – использование ключевого слова synchronized для конструктора является синтаксической ошибкой.

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

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

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

Это верно только для разных потоков.

Один и тот же поток может вызвать синхронизированный метод, внутри него – другой синхронизированный метод на том же экземпляре. И это будет повторная блокировка.

Поскольку этот поток владеет монитором, проблем второй вызов не создаст.

Это верно только для вызовов методов одного экземпляра.

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

Другой способ создания синхронизированного кода – синхронизированные блоки.

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



Когда один поток заходит внутрь блока кода, помеченного словом synchronized, то Java-машина тут же блокирует монитор объекта, который указан в круглых скобках после слова synchronized.

Больше ни один поток не сможет зайти в этот блок, пока наш поток его не покинет.

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

Для нестатических методов, синхронизация метода эквивалентна синхронизации тела метода с объектом this.



Для статических методов, синхронизация метода эквивалентна синхронизации тела метода с объектом Class.

Предположим, что класс имеет два поля экземпляра: c1 и c2, которые никогда не используются вместе.



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

Вместо использования синхронизированных методов или использования блокировки this, мы создаем два объекта исключительно для обеспечения блокировок.

Страница 5