Page 148 - 4868
P. 148
Ошибка! Стиль не определен. 146
this.intrinsicLock.unlock();
}
}
Наприклад, замість явного блокування можна просто оголосити метод
transfer() визначений в класі Bank із ключовим словом synchronized.
При цьому, вбудоване блокування має єдину пов’язану з нею умову.
Окрім звичайних методів, допускається оголошувати синхронізованими
також і статичні методи. Коли викликається такий метод, то він захоплює
вбудоване блокування об’єкта відповідного класу. Тобто, якщо в класі Bankє
статичний синхронізований метод, то при його виклику захоплюється
блокування об’єкта типу Bank.class. У результаті до такого об’єкта не
може отримати доступ жодний інший потік та синхронізований статичний
метод того ж класу.
Вбудованим блокуванням притаманні деякі обмеження, в тому числі
наведені нижче:
1. Не можливо перервати потік, який намагається захопити блокування.
2. Не можливо вказати час очікування, намагаючись захопити
блокування.
3. Наявність єдиної умови на блокування може виявитися неефективним.
Що ж все-таки краще використовувати: об’єкти типу Lock та
Condition чи синхронізовані методи? Нижче наведені деякі рекомендації,
які дають відповідь на це питання:
1. Краще не користуватися ні об’єктами типу Lock / Condition, ні
ключовим словом synchronized. У більшості випадків замість цього можна
використати відповідний клас з пакету java.util.concurrent, який
реалізує автоматичне блокування.
2. Якщо для розв’язання конкретної задачі підходить ключове слово
synchronized, то його неодмінно потрібно використати. У даному випадку
доведеться написати набагато менше коду, а отже, допустити менше
помилок.
3. Об’єкти типу Lock / Condition необхідно використовувати тільки у
тому випадку, якщо дійсно потрібні додаткові механізми керування процесом
синхронізації.
Як було згадано раніше, у кожного об’єкта в мові Java є власне
вбудоване блокування. Потік може захопити дане блокування, викликавши
синхронізований метод. Проте, існують й інший механізм захоплення
блокування, що полягають у входженні в синхронізований блок.
Припустимо, що необхідно синхронізувати доступ до об’єктів класів, які
не були призначені для багатопотокового доступу. Тобто клас не визначає
синхронізованих методів. Більше того, клас був написаний стороннім
розробником і у нас немає доступу до його вихідного коду. Отже, додати
слово synchronized до оголошення відповідних методів класу не можливо.
Проте, існує досить просте рішення даної проблеми, що полягає у виклику
методів такого класу в блоці позначеного ключовим словом synchronized.