Java ExecutorService е интерфейсът, който ни позволява да изпълняваме задачи на нишки асинхронно. Интерфейсът Java ExecutorService присъства в пакета java.util.concurrent. ExecutorService помага при поддържането на набор от нишки и им възлага задачи. Той също така предоставя възможност за поставяне на задачи в опашка, докато има налична свободна нишка, ако броят на задачите е повече от наличните нишки.
Методи на Java ExecutorService
Метод | Описание |
---|---|
boolean awaitTermination(дълго изчакване, TimeUnit единица) | Този метод блокира задачата да влезе в ExecutorService, докато всички задачи не завършат след заявката за изключване, или настъпи даденото време за изчакване, или текущата нишка бъде прекъсната, което от двете се случи първо. |
списък | Този метод изпълнява списъка с дадени задачи и връща списъка с фючърси, които съдържат резултатите от всички задачи, когато са изпълнени. |
списък | Този метод изпълнява списъка с дадени задачи и връща списъка с фючърси, които съдържат резултатите от всички задачи, когато са завършени или времето за изчакване изтече, което от двете настъпи първо. |
T invokeAny(Колекция extends Callable>задачи) | Този метод изпълнява списъка с дадени задачи и връща резултата от една задача, която е завършена, без да създава изключение. |
T invokeAny(Колекция extends Callable>задачи, дълго изчакване, TimeUnit единица) | Този метод изпълнява дадения списък от задачи и връща резултата от една задача, която е завършена, без да хвърля изключение преди изтичането на времето за изчакване. |
булево isShutdown() | Този метод връща дали дадения изпълнител е спрян или не. |
boolean isTerminated() | Този метод връща true, ако всички задачи са изпълнени след изключване. |
void shutdown() | Този метод позволява изпълнение на предварително изпратени задачи към ExecutorService и не позволява приемането на други задачи. |
Списък shutdownNow() | Този метод спира всички активно изпълняващи се задачи, спира изпълнението на поставени в опашка задачи и връща списъка със задачи, които са в опашка. |
Бъдещо подаване (извикваема задача) | Този метод изпраща задача за връщане на стойност за изпълнение и връща бъдещето, което представлява чакащия резултат от задачата. |
Бъдещо изпращане (изпълнима задача) | Този метод изпраща задача за изпълнение и връща бъдеще, представляващо тази задача. Връща нула при успешно завършване. |
Бъдещо изпращане (изпълнима задача, T резултат) | Този метод изпраща задача за изпълнение и връща бъдеще, представляващо тази задача. |
Проста програма на 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, както следва-
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, можем да използваме следните методи-
- изпълни (изпълнима задача)
- изпращане (изпълнима задача) / изпращане (извикваема задача)
- invokeAny(Колекция extends Callable>задачи)
- invokeAll(Колекция extends Callable>задачи)
Пример за присвояване на задача на ExecutorService с помощта на метода execute().
Методът execute() на Java ExecutorService приема обект, който може да се изпълнява, и изпълнява задачата си асинхронно. След като направим извикването на метода за изпълнение, ние извикваме метода за изключване, който блокира всяка друга задача на опашка в 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().
индекс на java
Методът 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() приема колекция от 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'; } }); 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().