Page 264 - 6253
P. 264

розблокують призупинені потоки. Виклик методу wait() або notifyAll() рівнозначний

            наступному коду:

                  buildConditional.await();
                  buildConditional.signalAll();
                  Отже, використання ключового слова synchronized дозволяє суттєво скоротити


            вихідний  код  програми.  В  даному  випадку,  блокування  керує  потоками,  які
            намагаються  увійти  в  метод  synchronized,  а  умова  керує  потоками,  що  викликали


            метод wait().
                  Поля та змінні типу volatile. Часто для захисту одного або двох полів класу від


            асинхронного  доступу  потрібно  синхронізувати  доступ  до  усього  об’єкта,  що  є

            занадто  затратною  операцією  в  плані  розподілу  процесорного  часу.  Зрештою,  що

            може статися  поганого під час асинхронних операцій запису або зчитування поля

            екземпляру класу? На жаль, сучасні процесори і компілятори можуть бути джерелом

            для появи великої кількості помилок під час таких нескладних операцій:

                  1. Комп’ютери  з  декількома  процесорами  можуть  тимчасово  утримувати

            значення  з  пам’яті  в  регістрах  або  локальних  кешах.  Як  наслідок,  потокам,  що

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

            тій же області пам’яті.

                  2. Компілятори можуть змінювати порядок виконання команд для досягнення

            максимальної продуктивності програми. При цьому, результат виконання програми

            жодним  чином  не  міняється,  але  робиться  припущення,  що  значення  в  пам’яті

            змінюються  тільки  явними  командами  в  коді.  Проте,  в  багатопотоковій  програмі

            значення в пам’яті може бути змінено виконанням будь-якого потоку.

                  Ключове  слово  volatile  використовується  для  встановлення  неблокуючого

            режиму  синхронізованого  доступу  до  поля  класу.  У  випадку,  коли  поле  класу

            оголошене із модифікатором volatile, то компілятор і віртуальна машина враховують

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

                  Припустимо,  що  у  класі  визначено  поле  done  типу  boolean,  значення  якого

            встановлюється в одному потоці і зчитується в іншому. Для синхронізації доступу

            до  даного  поля  можна  використати  механізм  вбудованого  блокування  під  час

            проектування відповідного класу:

                  private boolean done;


                                                              263
   259   260   261   262   263   264   265   266   267   268   269