Page 257 - 6253
P. 257
відповідним блокуванням. Якщо під час виконання методу transfer() буде виявлено,
що коштів на рахунку недостатньо, то він виконає виклик методу await(), який
переводить поточний потік в режим очікування, що дає змогу поповнити рахунок в
іншому потоці:
sufficientFunds.await();
Існує істотна відмінність між потоком, що очікує можливості захопити
блокування, і потоком, що викликав метод await(). Виклик методу await()
переводить потік в режим очікування, визначений для даної умови. Потік
залишається в режимі очікування доти, поки інший потік не викличе метод
signalAll() по тій же умові очікування.
Коли сума коштів на рахунку стане більшою amount, то потік в якому було
виконано переказ коштів повинен викликати наступний код:
sufficientFunds.signalAll();
При цьому, планувальник потоків переводить усі потоки, що задовольняють
умові очікування в активний стан, і як тільки об’єкт блокування стане доступним,
один з цих потоків захопить його і продовжить своє виконання з того місця, де він
був призупинений, отримавши керування після виклику методу await().
У даний момент потік знову повинен перевірити умову очікування, проте немає
жодних гарантій, що вона тепер буде виконаною. Адже метод signalAll() просто
сигналізує призупиненим потокам про те, що умова тепер може бути задоволеною і,
що її варто перевірити заново.
Також важливо, щоб метод signalAll() був викликаний в будь-якому іншому
потоці, відмінному від потоку, що виконав виклик метода await(), оскільки він не
має можливості повторно активізувати самого себе. Якщо жоден із потоків не
«подбає» про повторну активацію призупиненого потоку, то його виконання ніколи
не відновиться, що може призвести до так званого взаємного блокування. Якщо всі
інші потоки будуть заблоковані, а метод await() буде викликаний з останнього
активного потоку без попереднього виклику методу signalAll(), то даний потік також
виявиться заблокованим.
Що стосується виклику методу signalAll(), то тут існує певне емпіричне
правило, яке говорить, що викликати даний метод потрібно при такій зміні стану
об’єкта, який може бути вигідний призупиненим потокам. Наприклад, щоразу, коли
256