Page 150 - 4868
P. 150

Ошибка! Стиль не определен.                                                              148

                       System.out.println();
                     }

                     Такий підхід цілком працездатний, але він повністю залежить від того
               факту, що вбудоване блокування використовується в класі Vector для всіх
               його  методів.  З  цієї  причини,  клієнтське  блокування  є  досить  ненадійним
               прийомом, і тому зазвичай воно не рекомендується до застосування.


                     20.2. Керування міжпотоковими комунікаціями
                     У попередніх прикладах для блокування інших потоків від асинхронного
               доступу  до  методів  використовувалися  неявні  монітори  об’єктів.  Проте,  в
               мові  Java  можна  досягнути  більш  детального  рівня  контролю  за  рахунок
               міжпотокових комунікацій.
                     Як уже було сказано раніше, багатопотоковість замінила програмування
               на  основі  циклів  подій  за  рахунок  поділу  задач  на  дискретні,  логічно
               відокремлені  одиниці.  Проте,  це  не  єдина  перевага  потоків.  Вони  також
               виключають  опитування,  що  зазвичай  реалізуються  у  вигляді  циклу,  який
               використовується  для  періодичної  перевірки  деякої  умови.  Наприклад,
               розглянемо класичну  задачу в якій один потік створює деякі дані, а  інший
               обробляє їх. Також припустимо, що постачальник даних перш ніж створити
               нові  дані  повинен  очікувати,  поки  споживач  не  завершить  свою  роботу.  У
               системах  із  опитуванням  споживач  даних  витрачає  цикли  процесора  на
               очікування даних від постачальника. Як тільки постачальник завершить свою
               роботу,  він  повинен  розпочати  опитування,  очікуючи  завершення  роботи
               споживача даних, і т.д.
                     З метою уникнення опитувань, мова Java реалізує елегантний механізм
               міжпотокових  комунікацій  з  використанням  методів  wait(),  notify()  та
               notifyAll().

                     Дані методи оголошені в класі Object з модифікатором доступу final,
               тому  вони  доступні  з  будь-якого  об’єкту.  Усі  три  методи  можуть  бути
               викликані  тільки  із  синхронізованого  контексту.  Хоча  з  точки  зору  своєї
               реалізації вони концептуально складні, правила застосування даних методів
               досить прості:
                     1. Метод wait() призупиняє потік та виводить його із монітору до того
               часу, поки будь-який  інший потік не  увійде у  той же монітор  і не викличе
               метод notіfy().
                     2. Метод  notify()  відновлює  роботу  потоку,  що  викликав  метод
               wait() із того ж самого об’єкта.
                     3. Метод  notifyAll()  відновлює  роботу  всіх  потоків,  які  викликали
               метод wait() і одному із потоків дається доступ до монітору.
                     Існують  також  додаткові  форми  методу  wait(),  що  дозволяють
               вказувати час очікування по закінченню якого потік поновлює свою роботу.
                     Перш ніж розглядати приклад, який демонструє міжпотокову взаємодію,
               необхідно  зробити  одне  важливе  зауваження.  Хоча  метод  wait()  зазвичай
               перебуває в стані очікування до того часу, поки не буде викликаний метод
   145   146   147   148   149   150   151   152   153   154   155