Page 181 - 6571
P. 181

// об’єкт класу ReentrantLock, реалізує інтерфейс L
            ck
                    private Lock bankLock = new ReentrantLock();
                    ...

                    public void transfer(int from, int to, int amount) {
                      bankLock.lock();
                      try {
                        System.out.print(Thread.currentThread());
                        accounts[from] = accounts[from] - amount;
                        System.out.printf("%10.2f з %d до %d", amount,
                                      from, to);
                        accounts[to] = accounts[to] + amount;
                        System.out.printf("Загальний баланс: %10.2f%n",
                                      getTotalBalance());
                      } finally {
                        bankLock.unlock();
                      }
                    }
                  }

                  Припустимо,  що  в  одному  із  потоків  викликається  метод

            transfer()  і  даний  потік  призупиняється  під  час  його
            виконання.  Припустимо  також,  що  в  цей  момент  другий  потік
            також        викликає        метод       transfer(),            проте,       він     буде

            дезактивований  і  змушений  очікувати,  поки  виконання  методу
            transfer()  не  завершиться  в  першому  потоці.  І  тільки  тоді,
            коли  перший  потік  зніме  блокування,  другий  потік  зможе

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

            Bank  є  свій  власний  об’єкт  типу  ReentrantLock.  Якщо  два
            потоки  спробують  звернутися  до  одного  і  того  ж  об’єкту  типу

            Bank,  то  один  із  них  буде  заблоковано.  Але  якщо  два  потоки
            звертаються  до  різних  об’єктів  типу  Bank,  то  кожен  із  них
            отримає  своє  блокування  і  жоден  з  потоків  при  цьому  не  буде
            заблокованим, оскільки кожен із них працює з своїм екземпляром

            класу Bank.
                  Описаний             вище         вид         блокування             називається
            реентерабельним,  оскільки  потік  може  повторно  захоплювати

            блокування,  яким  він  уже  володіє.  Для  кожного  блокування

                                                        180
   176   177   178   179   180   181   182   183   184   185   186