Page 185 - 6571
P. 185
bankLock.lock();
try {
while (accounts[from] < amount)
sufficientFunds.await();
// переказати кошти
sufficientFunds.signalAll();
} finally {
bankLock.unlock();
}
}
Слід також мати на увазі, що виклик методу signalAll() не
спричиняє негайну активацію призупиненого потоку. Він лише
розблокує потоки, що перебувають в стані очікування, щоб вони
мали можливість змагатися за об’єкт блокування.
Існує також метод signal(), який розблокує тільки один
потік із тих що перебувають в очікуванні, вибираючи його при
цьому випадковим чином. Це більш ефективно, ніж
розблоковувати всі заблоковані потоки, хоча в даному випадку
існує певна небезпека. Якщо випадково обраний потік виявить,
що ще не може продовжити свого виконання, то він знову
перейде в режим очікування. І якщо жодний інший потік не
викличе знову метод signal(), то система перейде в стан
взаємного блокування.
Отже, підведемо короткі підсумки, перерахувавши ключові
моменти, що стосуються блокувань та умов:
1. Блокування захищають критичні секції коду, дозволяючи
при цьому виконувати даний код тільки одному потоку в
конкретний момент часу.
2. Блокування використовуються для керування потоками, які
намагаються увійти в захищену секцію коду.
3. Кожен умовний об’єкт керує потоками, які увійшли в
захищену секцію коду, але поки що не в змозі продовжити своє
виконання.
Запитання для самоперевірки
1. Яким чином можна відслідкувати завершення потоку у
мові Java?
2. Який призначення методу isAlive() у мові Java?
3. Яке призначення методу join() у мові Java?
184