Page 178 - 6571
P. 178

2. Методи          не      зобов’язані          бути        синхронізованими
                  (synchronized).
                        3. Клієнтам доступне керування вбудованим блокуванням.
                        Ці  пункти  свідчать  про  явне  нехтування  вимогами  безпеки,

                  викладеними Пером Брінчем Хансеном (Fer Brinch Hansen) і Тоні
                  Хоаром (Тоnу Ноаrе) в 1970-х роках.
                        Щоб        уникнути         пошкодження             даних,        що      спільно

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

                  рахунками.  Згенеруємо  випадковим  чином  декілька  транзакції,
                  що  переводять  гроші  з  одного  рахунку  на  інший.  Кожна
                  транзакція  переміщає  довільну  суму  грошей  з  рахунку,  що

                  обслуговується  поточним  потоком,  на  іншій  довільно  обираний
                  рахунок.
                        У  коді,  що  імітує  роботу  банку  визначено  клас  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()  *  Ma
                  h.random());

                                                             177
   173   174   175   176   177   178   179   180   181   182   183