Page 255 - 6571
P. 255

конання методу transfer() буде виявлено, що коштів на раху-
            нку  недостатньо, то він виконає  виклик  методу await(), який
            переводить поточний потік в режим очікування, що дає змогу по-

            повнити рахунок в іншому потоці.

                  while (account - amount < 0) {
                     sufficientFunds.await();
                  }

                  Існує істотна відмінність між потоком, що очікує можливості
            захопити  блокування,  і  потоком,  що  викликав  метод  await().

            Виклик методу await() переводить потік в режим очікування,
            визначений для даної умови. Потік залишається в режимі очіку-
            вання доти, поки інший потік не викличе метод signalAll()

            по тій же умові очікування.

                  sufficientFunds.signalAll();

                  При цьому, планувальник потоків переводить усі потоки, що
            задовольняють  умові  очікування  в  активний  стан,  і  як  тільки
            об’єкт блокування стане доступним, один з цих потоків захопить

            його і продовжить своє виконання з того місця, де він був призу-
            пинений, отримавши керування після виклику методу await().
                  Також важливо, щоб метод signalAll() був викликаний в

            будь-якому  іншому  потоці,  відмінному  від  потоку,  що  виконав
            виклик метода await(), оскільки він не має можливості повто-

            рно активізувати самого себе. Якщо жоден із потоків не «подбає»
            про повторну активацію призупиненого потоку, то його виконан-
            ня ніколи не відновиться, що може призвести до так званого вза-
            ємного блокування. Якщо всі інші потоки будуть заблоковані, а

            метод await() буде викликаний з останнього активного потоку
            без попередньоговиклику методу signalAll(), то даний потік

            також виявиться заблокованим.
                  Існує  також  метод  signal(),  який  розблокує  тільки  один
            потік  із  тих  що  перебувають  в  очікуванні,  вибираючи  його  при

            цьому випадковим чином. Це більш ефективно, ніж розблокову-
            вати всі заблоковані потоки, хоча в даному випадку існує певна
            небезпека. Якщо випадково обраний потік виявить, що ще не мо-

            же продовжити свого виконання,  то він знову перейде в режим
            очікування. І якщо жодний інший потік не викличе знову метод
            signal(), то система перейде в стан взаємного блокування.

                                                        254
   250   251   252   253   254   255   256   257   258   259   260