Page 256 - 6571
P. 256
У попередньому прикладі для блокування інших потоків від
асинхронного доступу до методів використовувалися неявні мо-
нітори об’єктів. Проте, в мові Java можна досягнути більш дета-
льного рівня контролю за рахунок міжпотокових комунікацій.
Раніше для періодичної перевірки деякої умови використову-
вався механізм на основі опитувань, що зазвичай реалізуються у
вигляді вічного циклу. З метою уникнення опитувань, мова Java
реалізує елегантний механізм міжпотокових комунікацій з вико-
ристанням методів wait(), notify() та notifyAll().
Дані методи оголошені в класі Object з модифікатором дос-
тупу final, тому вони доступні з будь-якого об’єкту. Усі три
методи можуть бути викликані тільки із синхронізованого кон-
тексту. Хоча з точки зору своєї реалізації вони концептуально
складні, правила застосування даних методів досить прості:
1. Метод wait() призупиняє потік та виводить його із моні-
тору до того часу, поки будь-який інший потік не увійде у той же
монітор і не викличе метод notіfy().
2. Метод notify() відновлює роботу потоку, що викликав
метод wait() із того ж самого об’єкта.
3. Метод notifyAll() відновлює роботу всіх потоків, які
викликали метод wait() і одному із потоків дається доступ до
монітору.
Виклик методу wait() та notifyAll() рівнозначний на-
ступному коду:
sufficientFunds.await();
sufficientFunds.signalAll();
Хоча метод wait() зазвичай перебуває в стані очікування
до того часу, поки не буде викликаний метод notify() або n
tifyAll(), проте існує ймовірність, що в дуже рідкісних випа-
дках призупинений потік може бути поновлений підробленим си-
гналом. Через цю малоймовірну можливості Oracle рекомендує
виконувати виклики методу wait() всередині циклу, що переві-
ряє умову очікування потоку.
while (account - amount < 0) {
wait();
}
255