Page 261 - 6571
P. 261

final Map accounts = new HashMap();

                  Змінна accounts стане доступною для інших потоків після

            виконання  конструктора  HashMap().  Якщо  не  оголосити  її  із
            модифікатором  final,  то  немає  жодної  гарантії,  що  оновлене

            значення змінної accounts виявиться доступним з інших пото-
            ків. Якщо виконання конструктора класу HashMap буде перерва-

            но іншим потоком, то значення змінної accounts може вияви-
            тися рівним null. Проте, потрібно також розуміти, що викорис-

            тання модифікатора final під час створення об’єкта не робить
            операції  над  ним  потокобезпечними.  Якщо  стан  об’єкта  зміню-
            ється та зчитується в декількох потоках, то як і раніше необхідна

            його синхронізація.
                  Працювати  з  потоками  напряму  не  зовсім  зручно,  тому  в
            2004 році в Java 5 було додано Concurrency API. Дане API знахо-

            диться в пакеті java.util.concurrent і містить велику кіль-
            кість корисних класів та методів для багатопотокового програму-
            вання.  Для  ефективного  керування  множиною  потоків  у  Java  5

            через Concurrency API реалізований механізм пулу потоків. Пул
            потоків гарантує, що потік не буде втрачено і допомагає збалан-
            сувати програмний додаток за кількістю потоків і частоті їх ство-

            рення.
                  Concurrency API вводить поняття сервісу-виконавця (Executor
            Service) – високорівневу заміну безпосередній роботі з потоками.
            Виконавці виконують завдання асинхронно і зазвичай використо-

            вують пул потоків.
                  Створення  екземпляру  сервісу-виконавця  робиться  або

            вручну через конкретні імплементації інтерфейсів Scheduled
            hreadPoolExecutor  чи  ThreadPoolExecutor,  або  через
            використання фабрики класу Executors. Наприклад, якщо пот-

            рібно                 створити                   пул                 з               2-ма
            потоками, то це можна зробити наступним чином:

                  ExecutorService service =
                       Executors.newFixedThreadPool(2);

                  Якщо потрібно використовувати пул потоків на основі кешу,
            який створює потоки в міру необхідності, а також перевикорис-

            товує неактивні потоки і підчищає потоки, які були неактивні де-
            який час, то це можна зробити наступним чином:

                                                        260
   256   257   258   259   260   261   262   263   264   265   266