Page 183 - 6571
P. 183

// очікувати
                      }
                      // перевести кошти
                    } finally {

                      bankLock.unlock();
                    }
                  }

                  Проте,  що  робити,  якщо  на  рахунку  немає  достатньої
            кількості  коштів?  Єдине  рішення  –  це  очікувати  до  того  часу,
            поки  рахунок  не  буде  поповнено  під  час  виконання  іншого

            потоку.  Проте,  у  представленому  прикладі  потік  володіє
            монопольним доступом до об’єкта bankLock, тому жоден інший
            потік  не  в  змозі  виконати  поповнення  рахунку.  Тому  єдиним
            правильним рішенням є використання умовного об’єкту.

                  З будь-яким об’єктом блокування може бути пов’язаний один
            або  декілька  умовних  об’єктів,  які  створюються  за  допомогою

            фабричного  методу  newCondition().  Кожному  умовному
            об’єкту можна присвоїти ім’я,  що буде асоціюватися з  умовою,
            яку  він  представляє.  Наприклад,  об’єкт,  що  представляє  умову
            «достатньо коштів», визначається наступним чином:

                  class Bank {
                    private Condition sufficientFunds;
                    ...
                    public Bank() {
                      ...
                      sufficientFunds = bankLock.newCondition();

                    }
                  }

                  Фабричний  метод  newCondition()  повертає  умовний
            об’єкт,  пов’язаний  з  відповідним  блокуванням.  Якщо  під  час
            виконання  методу  transfer()  буде  виявлено,  що  коштів  на

            рахунку  недостатньо,  то  він  виконає  виклик  методу  await(),
            який  переводить  поточний  потік  в  режим  очікування,  що  дає
            змогу поповнити рахунок в іншому потоці:

                  sufficientFunds.await();

                  Існує істотна відмінність між потоком, що очікує можливості
            захопити  блокування,  і  потоком,  що  викликав  метод  await().

            Виклик  методу  await()  переводить  потік  в  режим  очікування,


                                                        182
   178   179   180   181   182   183   184   185   186   187   188