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
   251   252   253   254   255   256   257   258   259   260   261