Page 69 - 4657
P. 69

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

                  Взаємодія підпроцесів


                 У  Java  мається  елегантний  механізм  спілкування  між
            підпроцесами, заснований на методах wait, notify і notifyAll. Ці
            методи реалізовані, як final-методи класу Object, так що вони є в
            будь-якому Java-класі. Усі ці методи повинні викликатися тільки
            із синхронізованих методів. Правила використання цих методів
            дуже прості:
                 - wait  -  приводить  до  того,  що  поточний  підпроцес  віддає
                  керування і переходить у режим чекання - доти поки інший
                  під-процес не викликає метод notify з тим же об'єктом;
                 -   notify - виводить зі стану чекання перший з підпроцесів,
                  що викликали wait з даним об'єктом;
                 -   notifyAll - виводить зі стану чекання всі підпроцеси, що
                  викликали wait з даним об'єктом.
                 Нижче приведений приклад програми з наївною реалізацією
            проблеми  постачальник-споживач.  Ця  програма  складається  з
            чотирьох простих класів: класу Q, що представляє собою нашу
            реалізацію     черги,   доступ     до    якої   ми    намагаємося
            синхронізувати; постачальника (клас Producer), що виконується
            в окремому підпроцесі і поміщає дані в чергу; споживача (клас
            Consumer), що теж представляє собою підпроцес і витянуті дані
            з черги; і, нарешті, крихітного класу PC, що створює по одному
            об'єкті кожного з перерахованих класів.

            class Q {
            int n;
                                                                             67
   64   65   66   67   68   69   70   71   72   73   74