Page 180 - 6571
P. 180
нормальне завершення методу transfer() до того, як його потік
втратить керування.
19.3 Використання об’єктів блокування
У мові Java існує два механізми для захисту критичної секції
коду від паралельного доступу. Один із них полягає у
використанні ключового слова synchronized, а інший – у
використанні класу ReentrantLock, що з’явився у версії
JavaSE 5.0. Ключове слово synchronized автоматично
забезпечує блокування, як і пов’язана з ним умова, яку зручно
використовувати в більшості випадків, коли необхідно
реалізувати явне блокування.
Захист блоку коду засобами класу ReentrantLock в
загальному випадку виглядає наступним чином:
myLock.lock(); // об’єкт типу ReentrantLock
try {
критична секція коду;
} finally {
// зняти блокування, навіть у випадку генерації виня-
тку
myLock.unlock();
}
Дана конструкція гарантує, що тільки один потік в
конкретний момент часу зможе увійти в критичну секцію коду.
Як тільки потік заблокує об’єкт блокування, то жоден інший
потік не зможе виконати виклик методу lock() оскільки під час
спроби це зробити вони будуть дезактивовані доти, поки перший
потік не зніме блокування з об’єкта блокування. Також дуже
важливо розмістити виклик методу unlock() у блоці finally,
оскільки блокування має бути знято навіть у випадку, якщо під
час виконання коду з критичної секції буде згенеровано виняток.
В іншому випадку інші потоки залишаться заблокованими
назавжди.
Виконаємо блокування для захисту критичної секції коду з
методу transfer() що визначений у класі Bank.
public class Bank {
179