Page 152 - 4868
P. 152

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

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

                     Припустимо, що у класі визначено поле done типу boolean, значення
               якого  встановлюється  в  одному  потоці  і  зчитується  в  іншому.  Для
               синхронізації  доступу  до  даного  поля  можна  використати  механізм
               вбудованого блокування під час проектування відповідного класу:
                     private boolean done;
                     public synchronized boolean isDone() { return done; }
                     public synchronized void setDone() { done = true; }

                     Проте, можливо використання вбудованого блокування є не найкращою
               ідеєю.  Адже  методи  isDone()  та  setDone()  можуть  виявитися
               заблокованими,  якщо  інший  потік  заблокував  об’єкт  відповідного  класу.
               Інший  варіант  полягає  у  використанні  для  поля  done  об’єкту  типу  Lock.
               Проте,  у  цьому  випадку  потрібно  написати  багато  рутинного  коду,  тому  є
               зміст  оголосити  поле  done  з  модифікатором  volatile  як  це  зроблено
               нижче:

                     private volatile boolean done;
                     public boolean isDone() { return done; }
                     public void setDone() { done = true; }
                     Під  час  роботи  із  змінними  типу  volatile  не  гарантується  жодна
               атомарність операцій. Наприклад, наведений нижче метод не гарантує зміни
               значення поля done на протилежне.

                     public void flipDone() {
                       done =! done; // не атомарна операція
                     }

                     Поля та змінні типу final. Ще одним із варіантів отримати надійний
               доступ до спільного поля з декількох потоків є використання ключового поля
               final. Розглянемо наступний рядок коду:
                     final Map accounts = new HashMap();

                     Змінна accounts стане доступною для інших потоків після виконання
               конструктора HashMap(). Якщо не оголосити її із модифікатором final, то
               немає  жодної  гарантії,  що  оновлене  значення  змінної  accounts  виявиться
               доступним  з  інших  потоків.  Якщо  виконання  конструктора  класу  HashMap
               буде  перервано  іншим  потоком,  то  значення  змінної  accounts  може
               виявитися  рівним  null.  Проте,  потрібно  також  розуміти,  що  використання

               модифікатора final під  час створення об’єкта не робить  операції  над ним
               потокобезпечними. Якщо стан об’єкта змінюється та зчитується в декількох
               потоках, то як і раніше необхідна його синхронізація.
   147   148   149   150   151   152   153   154   155   156   157