Java ExecutorService — це інтерфейс, який дозволяє асинхронно виконувати завдання в потоках. Інтерфейс Java ExecutorService присутній у пакеті java.util.concurrent. ExecutorService допомагає підтримувати пул потоків і призначає їм завдання. Він також надає можливість ставити завдання в чергу, доки не буде доступний вільний потік, якщо кількість завдань перевищує кількість доступних потоків.
Методи Java ExecutorService
метод | опис |
---|---|
логічне значення awaitTermination (тривалий час очікування, одиниця вимірювання часу) | Цей метод блокує завдання для входу в ExecutorService, доки всі завдання не будуть завершені після запиту на завершення роботи, або не настане заданий час очікування, або поточний потік буде перервано, залежно від того, що станеться раніше. |
Список | Цей метод виконує список заданих завдань і повертає список ф’ючерсів, які містять результати всіх завдань після виконання. |
Список | Цей метод виконує список наданих завдань і повертає список ф’ючерсів, які містять результати всіх завдань після завершення або закінчення часу очікування, залежно від того, що відбудеться раніше. |
T invokeAny(Колекція extends Callable>завдання) | Цей метод виконує список наданих завдань і повертає результат одного завдання, яке було завершено без створення винятків. |
T invokeAny(Колекція extends Callable>завдання, тривалий час очікування, одиниця TimeUnit) | Цей метод виконує наданий список завдань і повертає результат одного завдання, яке було завершено без створення винятків до закінчення часу очікування. |
логічне isShutdown() | Цей метод повертає, чи вимкнено даний виконавець чи ні. |
логічний isTerminated() | Цей метод повертає true, якщо всі завдання виконано після завершення роботи. |
void shutdown() | Цей метод дозволяє виконувати завдання, надані раніше ExecutorService, і не дозволяє приймати будь-які інші завдання. |
Список shutdownNow() | Цей метод зупиняє всі активно виконувані завдання, зупиняє виконання завдань, що стоять у черзі, і повертає список завдань, які стоять у черзі. |
Майбутнє надсилання (завдання, яке можна викликати) | Цей метод надсилає на виконання завдання, що повертає значення, і повертає Future, який представляє очікуваний результат завдання. |
Майбутнє надсилання (виконуване завдання) | Цей метод надсилає завдання на виконання та повертає Future, що представляє це завдання. Він повертає null після успішного завершення. |
Майбутнє надсилання (виконуване завдання, результат T) | Цей метод надсилає завдання на виконання та повертає Future, що представляє це завдання. |
Проста програма Java ExecutorService
public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.execute(new Runnable() { @Override public void run() { System.out.println('ExecutorService'); } }); executorService.shutdown(); } }
Вихід:
У цій програмі ми створюємо ExecutorService з десятьма потоками та призначаємо йому анонімну виконувану реалізацію, яка виконує завдання друку «ExecutorService», а після завершення цього завдання ми вимикаємо службу виконавця.
Як використовувати Java ExecutorService
Створення екземпляра ExecutorService
Ми можемо використовувати Java ExecutorService для створення окремого потоку, пулу потоків або запланованого пулу потоків. Клас Executors надає фабричні методи для створення екземпляра ExecutorService наступним чином:
git додати все
ExecutorService executorService1 = Executors.newSingleThreadExecutor(); //Creates //a ExecutorService object having a single thread. ExecutorService executorService2 = Executors.newFixedThreadPool(10); // Creates a //ExecutorService object having a pool of 10 threads. ExecutorService executorService3 = Executors.newScheduledThreadPool(10); //Creates a scheduled thread pool executor with 10 threads. In scheduled thread //pool, we can schedule tasks of the threads.
Призначення завдань ExecutorServices
Щоб призначити завдання ExecutorService, ми можемо використати такі методи:
- виконати (виконуване завдання)
- submit(Runnable task) / submit(Callable task)
- invokeAny(Колекція extends Callable>завдання)
- invokeAll(Колекція extends Callable>завдання)
Приклад призначення завдання ExecutorService за допомогою методу execute().
Метод execute() Java ExecutorService приймає запущений об’єкт і виконує його завдання асинхронно. Після виклику методу execute ми викликаємо метод shutdown, який блокує будь-яке інше завдання в черзі в executorService.
public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() { @Override public void run() { System.out.println('ExecutorService'); } }); executorService.shutdown(); } }
Вихід:
ExecutorService
Приклад призначення завдання ExecutorService за допомогою submit()
Метод submit() приймає об’єкт, що виконується, і повертає об’єкт Future. Пізніше цей об’єкт використовується для перевірки статусу Runnable, чи завершено його виконання чи ні.
public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.submit(new Runnable() { @Override public void run() { System.out.println('ExecutorService'); } }); } }
Приклад призначення завдання ExecutorService за допомогою методу invokeAny().
10 відсотків від 60
Метод invokeAny() приймає колекцію об’єктів Callablle або об’єктів класів, що реалізують Callable. Цей метод повертає майбутній об’єкт викликаного об’єкта, який успішно виконується першим.
public class ExecutorServiceExample { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<callable> callables = new HashSet<callable>(); callables.add(new Callable() { public String call() throws Exception { return 'Task 1'; } }); callables.add(new Callable() { public String call() throws Exception { return 'Task 2'; } }); callables.add(new Callable() { public String call() throws Exception { return 'Task 3'; } }); String result = executorService.invokeAny(callables); System.out.println('result = ' + result); executorService.shutdown(); } } </callable></callable>
Вихід:
result = Task 1
Результат зберігає Завдання 1, оскільки перший успішно виконаний об’єкт, який можна викликати.
Приклад призначення завдання ExecutorService за допомогою методу invokeAll().
Метод invokeAll() приймає колекцію викликаних об’єктів із завданнями та повертає список майбутніх об’єктів із результатом усіх завдань.
public class ExecutorServiceExample { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<callable> callables = new HashSet<callable>(); callables.add(new Callable() { public String call() throws Exception { return 'Task 1'; } }); callables.add(new Callable() { public String call() throws Exception { return 'Task 2'; } }); callables.add(new Callable() { public String call() throws Exception { return 'Task 3'; } }); java.util.List<future> futures = executorService.invokeAll(callables); for(Future future : futures){ System.out.println('future.get = ' + future.get()); } executorService.shutdown(); } } </future></callable></callable>
Вихід:
future.get = Task 1 future.get = Task 3 future.get = Task 2
Як вимкнути ExecutorService
Коли ми виконаємо завдання, передані ExecutorService, ми повинні вимкнути його, оскільки ExecutorService виконує завдання в різних потоках. Якщо ми не вимкнемо ExecutorService, потоки продовжуватимуть працювати, а JVM не вимкнеться.
Процес вимкнення можна виконати трьома способами:
- метод shutdown().
- метод shutdownNow().
- метод awaitTermination().