Page 252 - 6253
P. 252

У коді, що імітує роботу банку визначено клас Bank та описано метод transfer().

            Даний  метод  переміщує  деяку  суму  грошей  з  одного  рахунку  на  інший.  Нижче

            наведено можливий вихідний код методу transfer() з класу Bank.

                  public void transfer(int from, int to, double amount) {
                     System.out.println(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());
                  }

                  Нижче наведено вихідний код класу TransferRunnable. Його метод run() виконує

            перевід  грошей  з  фіксованого  банківського  рахунку.  Для  кожної  транзакції  метод

            run()  вибирає  випадковий  рахунок  і  довільну  суму,  викликає  метод  transfer()  для

            об’єкта Bank, а потім переводить потік в стан очікування.

                  class TransferRunnable implements Runnable {
                     public void run() {
                        try {

                           int toAccount = (int) (bank.size() * Math.random());
                           double amount = maxAmount * Math.random();

                           bank.transfer(fromAccount, toAccount, amount);
                           Thread.sleep((int) (DELAY * Math.random()));
                        } catch (InterruptedException e) { }

                     }
                  }

                  Під  час  виконання  даної  програми,  невідомо,  яка  саме  сума  знаходиться  на
            будь-якому  банківському  рахунку  в  довільний  момент  часу.  Але  в  той  же  час


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


            знімаються  остаточно.  Наприкінці  кожної  транзакції  метод  transfer()  заново

            обчислює  кінцеву  суму  на  рахунках  і  виводить  її.  При  цьому  програма  працює  у

            вічному циклі.

                  Запустивши  програму  на  виконання,  можна  виявити,  що  через  деякий  час

            загальний  баланс  все-таки  зміниться.  Це  пов’язано  з  тим,  що  два  потоки

            намагаються одночасно оновити один і той же рахунок. Припустимо, що два потоки



                                                              251
   247   248   249   250   251   252   253   254   255   256   257