Język programowania Java działa bardzo wydajnie z aplikacje, które wymagają współbieżnego wykonywania zadań w wątku. Każdej aplikacji trudno jest wykonywać jednocześnie dużą liczbę wątków. Aby rozwiązać ten problem, pochodzi z ExecutorService, który jest interfejsem podrzędnym . W tym artykule omówimy funkcjonalność ExecutorService w Javie. Poniżej znajdują się tematy poruszone na tym blogu:
- Co to jest Framework Executora?
- ExecutorService w języku Java
- Implementacje Java ExecutorService
- ExecutorService Usage
- Runnable vs Callable
- ExecutorService Shutdown
Co to jest Framework Executora?
Dość łatwiej jest utworzyć i wykonać jeden lub dwa wątki jednocześnie. Ale staje się to trudne, gdy liczba wątków wzrasta do znacznej liczby. Duże aplikacje wielowątkowe będą miały jednocześnie setki wątków. Dlatego całkowicie sensowne jest oddzielenie tworzenia wątków od zarządzania wątkami w aplikacji.
Wykonawca to pomaga w tworzeniu i zarządzaniu wątkami w aplikacji. Plik pomaga w następujących zadaniach.
Tworzenie wątków: zapewnia różnorodne metody tworzenia wątków, które pomagają w równoczesnym uruchamianiu aplikacji.
Zarządzanie wątkami: zarządza również cyklem życia wątku. Nie musisz się martwić, czy wątek jest aktywny, zajęty lub martwy przed przesłaniem zadania do wykonania.
Przesyłanie i wykonywanie zadań: Struktura modułu wykonawczego zapewnia metody przesyłania zadań w puli wątków, a także umożliwia decydowanie, czy wątek zostanie wykonany, czy nie.
ExecutorService w języku Java
Jest to podinterfejs struktury wykonawczej, który dodaje pewne funkcje do zarządzania cyklem życia wątku aplikacji. Udostępnia również metodę submit (), która może akceptować zarówno uruchamialne, jak i wywoływalne obiekty.
W poniższym przykładzie utworzymy ExecutorService z pojedynczym wątkiem, a następnie prześlemy zadanie do wykonania wewnątrz wątku.
import java.util.concurrent.ExecutorService import java.util.concurrent.Executors public class Przykład {public static void main (String [] args) {System.out.println ('Inside:' + Thread.currentThread (). getName ( )) System.out.println ('tworzenie ExecutorService') ExecutorService executorservice = Executors.newSingleThreadExecutor () System.out.println ('tworzenie runnable') Runnable runnable = () -> {System.out.println ('inside: '+ Thread.currentThread (). GetName ())} System.out.println (' wyślij zadanie określone przez element wykonawczy do usługi executors ') executorservice.submit (uruchom)}}
Wynik: Inside: main tworzenie ExecutorService tworzenie runnable przesłać zadanie określone przez runnable do executorservice wewnątrz: pool-1-thread-1
Powyższe pokazuje, jak możemy stworzyć ExecutorService i wykonać zadanie wewnątrz executora. Jeśli zadanie zostało przesłane do wykonania, a wątek jest obecnie zajęty wykonywaniem innego zadania, zadanie będzie czekało w kolejce, aż wątek będzie mógł go wykonać.
Po uruchomieniu powyższego programu program nigdy się nie zakończy. Będziesz musiał go jawnie wyłączyć, ponieważ usługa wykonawcza nasłuchuje nowych zadań.
Implementacje Java ExecutorService
ExecutorService jest bardzo podobny do puli wątków. W rzeczywistości implementacja ExecutorService w java.util.concurrent pakiet jest implementacją puli wątków. Usługa ExecutorService ma następujące implementacje w pakiecie java.util.concurrent:
ThreadPoolExecutor
ThreadPoolExecutor wykonuje dane zadania przy użyciu jednego z wątków znajdujących się w wewnętrznej puli.
Tworzenie threadPoolExecutor
int corePoolSize = 5 int maxPoolSize = 10 long keepAliveTime = 5000 ExecutorService threadPoolExecutor = new threadPoolExecutor (corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue ())
ScheduledThreadPoolExecutor
Java.util.concurrent.ScheduledThreadPoolExecutor to usługa ExecutorService, która może zaplanować uruchamianie zadań z opóźnieniem lub powtarzanie ich w ustalonych odstępach czasu między każdym wykonaniem.
Przykład
ScheduledExecutorService scheduleexecutorservice = Executors.newScheduledThreadPool (5) ScheduledFuture Scheduledfuture = ScheduledExecutorService.schedule (new Callable () {public Object call () rzuca Exception {System.out.println ('execute') return 'nazwane'}}, 5, TimeUnit. SEKUNDY)
ExecutorService Usage
Istnieje kilka różnych sposobów delegowania zadań do ExecutorService.
wykonaj (do uruchomienia)
przesłać (do uruchomienia)
invokeAny ()
invokeAll ()
Wykonaj Runnable
Wykonanie Java ExecutorService (Runnable) przyjmuje obiekt java.lang.Runnable i wykonuje go asynchronicznie.
ExecutorService executorService = Executors.newSingleThreadExecutor () executorService.execute (new Runnable () {public void run () {System.out.println ('zadanie asynchroniczne')}}) executorService.shutdown ()
Nie ma sposobu, aby uzyskać wynik wykonania Runnable, ponieważ musisz użyć Callable.
Prześlij Runnable
Metoda przesyłania Java ExecutorService (Runnable) przyjmuje implementację Runnable i zwraca przyszły obiekt. Przyszły obiekt może zostać użyty do sprawdzenia, czy Runnable zakończył wykonywanie.
Future future = executorService.submit (new Runnable () {public void run () {System.out.println (: asynchronous task ')}}) future.get () // zwraca wartość null, jeśli zadanie zostało ukończone poprawnie.
Prześlij wywoływane
Metoda przesyłania Java ExecutorService (Callable) jest podobna do przesyłania (Runnable), ale używa Java Callable zamiast Runnable.
Future future = executorService.submit (new Callable () {public Object call () throws Exception {System.out.println ('Asynchronous callable') return 'Callable Result'}}) System.out.println ('future.get ( ) = 'future.get ())
Wynik: Asynchroous wywoływana future.get = wywoływalny wynik
invokeAny ()
Metoda invokeAny () pobiera kolekcję obiektów Callable. Wywołanie tej metody nie zwraca żadnej przyszłości, ale zwraca wynik jednego z wywoływalnych obiektów.
ExecutorService executorService = Executors.newSingleThreadExecutor () Setcallables = new HashSet () callables.add (new Callable () {public String call () throws Exception {return'task A '}}) callables.add (new Callable () {public String call () throws Exception {return'task B'} }) callables.add (new Callable () {public String call () throws Exception {return'task C '}}) String result = executorService.invokeAny (callables) System.out.println (' result = '+ result) executorService .zamknąć()
Po uruchomieniu powyższego kodu wynik się zmieni. Może to być Zadanie A, Zadanie B i tak dalej.
InvokeAll ()
Metoda invokeAll () wywołuje wszystkie obiekty Callable przekazane jako parametry. Zwraca przyszłe obiekty, których można użyć do uzyskania wyników wykonania każdego wywołania.
ExecutorService executorService = Executors.newSingleThreadExecutor () Setcallables = new HashSet () callables.add (new Callable () {public String call () throws Exception {return 'Task A'}}) callables.add (new Callable () {public String call () throws Exception {return 'Task B'} }) callables.add (new Callable () {public String call () throws Exception {return 'Task C'}}) List futures = executorService.invokeAll (callables) for (Future future: futures) {System.out.println ('future.get =' + future.get ())} executorService.shutdown ()
Runnable vs Callable
Funkcjonalne i wywoływalne interfejsy są do siebie bardzo podobne. Różnica jest widoczna w deklaracji interfejsy. Oba interfejsy reprezentują zadanie, które może być wykonywane jednocześnie przez wątek lub ExecutorService.
Deklaracja na żądanie:
publiczny interfejs Callable {public object call () rzuca wyjątek}
Deklaracja wykonalności:
publiczny interfejs Runnable {public void run ()}
Główna różnica między nimi polega na tym, że metoda call () może zwrócić obiekt z wywołania metody. Metoda call () może zgłosić plik while run () nie może.
stół Cassandra vs rodzina kolumn
anuluj zadanie
Możesz anulować zadanie przesłane do ExecutorService, po prostu wywołując metodę anulowania w przyszłości przesłanej po przesłaniu zadania.
future.cancel ()
ExecutorService Shutdown
Aby wątki nie działały nawet po zakończeniu wykonywania, należy zamknąć usługę ExecutorService.
zamknąć()
Aby zakończyć wątki wewnątrz ExecutorService, można wywołać metodę shutdown ().
executorService.shutdown ()
To prowadzi nas do końca tego artykułu, w którym dowiedzieliśmy się, jak możemy używać ExecutorService do wykonywania zadań w wątku. Mam nadzieję, że wszystko, co zostało Ci udostępnione w tym samouczku, jest dla Ciebie jasne.
Jeśli uważasz, że ten artykuł dotyczący „ExecutorService in Java” jest odpowiedni, zapoznaj się z zaufana firma zajmująca się edukacją online z siecią ponad 250 000 zadowolonych uczniów rozsianych po całym świecie.
Jesteśmy tutaj, aby pomóc Ci na każdym etapie Twojej podróży i opracować program nauczania przeznaczony dla studentów i profesjonalistów, którzy chcą zostać programistą Java. Kurs ma na celu zapewnienie przewagi w programowaniu w języku Java i szkolenie zarówno podstawowych, jak i zaawansowanych koncepcji języka Java, a także różnych lubić Hibernować & .
Jeśli napotkasz jakieś pytania, nie krępuj się zadawać je w sekcji komentarzy w „ExecutorService in Java”, a nasz zespół z przyjemnością odpowie.