Java ExecutorService je sučelje koje nam omogućuje asinkrono izvršavanje zadataka na nitima. Sučelje Java ExecutorService prisutno je u paketu java.util.concurrent. ExecutorService pomaže u održavanju skupa niti i dodjeljuje im zadatke. Također pruža mogućnost stavljanja zadataka u red dok ne bude dostupna slobodna nit ako je broj zadataka veći od dostupnih niti.
Metode Java ExecutorService
metoda | Opis |
---|---|
boolean awaitTermination(dugo vrijeme čekanja, Jedinica vremena) | Ova metoda blokira zadatak da uđe u ExecutorService dok se svi zadaci ne dovrše nakon zahtjeva za gašenjem, ili dok ne nastupi zadano vremensko ograničenje, ili se trenutna nit prekine, što god se dogodi prije. |
Popis | Ova metoda izvršava popis zadanih zadataka i vraća popis Futuresa koji sadrži rezultate svih zadataka kada se dovrše. |
Popis | Ova metoda izvršava popis zadanih zadataka i vraća popis Futuresa koji sadrži rezultate svih zadataka kada se dovrše ili istekne vrijeme čekanja, što god se prvo dogodi. |
T invokeAny(Zbirka extends Callable>zadaci) | Ova metoda izvršava popis zadanih zadataka i vraća rezultat jednog zadatka koji je dovršen bez izbacivanja iznimke. |
T invokeAny(Zbirka extends Callable>zadaci, dugo čekanje, Jedinica vremena) | Ova metoda izvršava popis zadanih zadataka i vraća rezultat jednog zadatka koji se dovrši bez izbacivanja iznimke prije isteka vremenskog ograničenja. |
Boolean isShutdown() | Ova metoda vraća je li dani izvršitelj ugašen ili ne. |
boolean isTerminated() | Ova metoda vraća true ako su svi zadaci izvršeni nakon gašenja. |
void shutdown() | Ova metoda omogućuje dovršavanje prethodno predanih zadataka ExecutorService-u i ne dopušta prihvaćanje drugih zadataka. |
Popis shutdownNow() | Ova metoda zaustavlja sve zadatke koji se aktivno izvršavaju, zaustavlja izvršavanje zadataka u redu čekanja i vraća popis zadataka koji su stavljeni u red čekanja. |
Buduća predaja (pozivi zadatak) | Ova metoda šalje zadatak koji vraća vrijednost na izvršenje i vraća Budućnost, koja predstavlja rezultat zadatka na čekanju. |
Buduće slanje (zadatak koji se može izvršiti) | Ova metoda šalje zadatak na izvršenje i vraća budućnost koja predstavlja taj zadatak. Vraća null nakon uspješnog završetka. |
Buduće slanje (izvršivi zadatak, T rezultat) | Ova metoda šalje zadatak na izvršenje i vraća budućnost koja predstavlja taj zadatak. |
Jednostavan program 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(); } }
Izlaz:
U ovom programu stvaramo ExecutorService s deset niti i dodjeljujemo mu anonimnu runnable implementaciju koja izvršava zadatak ispisa 'ExecutorService' i nakon završetka zadatka, gasimo izvršni servis.
Kako koristiti Java ExecutorService
Instanciranje ExecutorService
Java ExecutorService možemo koristiti za stvaranje jedne niti, skupa niti ili planiranog skupa niti. Klasa Executors pruža tvorničke metode za instanciranje ExecutorService na sljedeći način-
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.
Dodjeljivanje zadataka ExecutorServices
Da bismo dodijelili zadatak ExecutorServiceu, možemo koristiti sljedeće metode-
- izvrši (izvršivi zadatak)
- pošalji (zadatak koji se može izvršiti) / pošalji (zadatak koji se može pozvati)
- invokeAny(Zbirka extends Callable>zadaci)
- invokeAll(Zbirka extends Callable>zadaci)
Primjer dodjele zadatka ExecutorService-u pomoću metode execute().
Metoda execute() usluge Java ExecutorService preuzima objekt koji se može izvoditi i svoj zadatak obavlja asinkrono. Nakon što pozovemo metodu za izvršenje, pozivamo metodu za isključivanje, koja blokira bilo koji drugi zadatak na čekanju u 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(); } }
Izlaz:
ExecutorService
Primjer dodjele zadatka ExecutorService pomoću submit()
Metoda submit() preuzima objekt koji se može izvoditi i vraća objekt Future. Ovaj se objekt kasnije koristi za provjeru statusa Runnablea je li dovršio izvođenje ili ne.
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'); } }); } }
Primjer dodjele zadatka ExecutorService-u pomoću metode invokeAny().
Metoda invokeAny() uzima kolekciju Callablle objekata ili objekata klasa koje implementiraju Callable. Ova metoda vraća budući objekt pozivajućeg objekta koji se prvi uspješno izvršava.
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>
Izlaz:
result = Task 1
Rezultat pohranjuje Zadatak 1 kao prvi objekt koji se može pozvati prvi uspješno izvršen.
Primjer dodjele zadatka ExecutorService-u pomoću metode invokeAll().
Metoda invokeAll() uzima kolekciju pozivavih objekata koji imaju zadatke i vraća popis budućih objekata koji sadrže rezultat svih zadataka.
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>
Izlaz:
future.get = Task 1 future.get = Task 3 future.get = Task 2
Kako ugasiti ExecutorService
Nakon što završimo sa zadacima danim ExecutorServiceu, tada ga moramo isključiti jer ExecutorService izvršava zadatak na različitim nitima. Ako ne ugasimo ExecutorService, niti će nastaviti raditi, a JVM se neće ugasiti.
Proces gašenja može se izvesti na sljedeća tri načina:
- shutdown() metoda
- metoda shutdownNow().
- awaitTermination() metoda