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