Cos'è ExecutorService in Java e come crearlo?



Questo articolo copre il concetto di interfaccia secondaria Executor ExecutorService in Java con vari esempi per spiegare la creazione e la gestione dei thread in Java.

Il linguaggio di programmazione Java funziona in modo molto efficiente con applicazioni che richiedono l'esecuzione simultanea delle attività in un thread. Diventa difficile per qualsiasi applicazione eseguire contemporaneamente un numero elevato di thread. Quindi, per superare questo problema, viene fornito con ExecutorService che è una sotto-interfaccia di . In questo articolo, discuteremo la funzionalità di ExecutorService in Java. Di seguito sono riportati gli argomenti trattati in questo blog:

Cos'è Executor Framework?

È abbastanza più facile creare ed eseguire uno o due thread contemporaneamente. Ma diventa difficile quando il numero di thread aumenta a un numero significativo. Le applicazioni multi-thread di grandi dimensioni avranno centinaia di thread in esecuzione contemporaneamente. Pertanto ha perfettamente senso separare la creazione del thread dalla gestione del thread in un'applicazione.





L'esecutore è un ti aiuta a creare e gestire i thread in un'applicazione. Il ti aiuta nelle seguenti attività.

  • Creazione thread: fornisce una varietà di metodi per la creazione di thread che aiutano a eseguire le applicazioni contemporaneamente.



  • Gestione thread: gestisce anche il ciclo di vita del thread. Non devi preoccuparti se il thread è attivo, occupato o morto prima di inviare l'attività per l'esecuzione.

  • Invio ed esecuzione di attività: il framework Executor fornisce metodi per l'invio di attività nel pool di thread, inoltre dà il potere di decidere se il thread verrà eseguito o meno.

executorservice-executorservice in java -edureka

ExecutorService in Java Esempio

È una sottointerfaccia del framework executor che aggiunge alcune funzionalità per gestire il ciclo di vita del thread di un'applicazione. Fornisce anche un metodo submit () che può accettare sia runnable che callable oggetti.



Nell'esempio seguente, creeremo un ExecutorService con un singolo thread e quindi invieremo l'attività da eseguire all'interno del thread.

import java.util.concurrent.ExecutorService import java.util.concurrent.Executors public class Esempio {public static void main (String [] args) {System.out.println ('Inside:' + Thread.currentThread (). getName ( )) System.out.println ('Creating ExecutorService') ExecutorService executorservice = Executors.newSingleThreadExecutor () System.out.println ('creazione di un eseguibile') Runnable runnable = () -> {System.out.println ('dentro: '+ Thread.currentThread (). GetName ())} System.out.println (' invia l'attività specificata dall'eseguibile all'executorservice ') executorservice.submit (runnable)}}
 Produzione: Dentro: creazione principale ExecutorService creazione di un eseguibile invia l'attività specificata dall'eseguibile al servizio eseguibile all'interno: pool-1-thread-1

Quanto sopra mostra come possiamo creare un ExecutorService ed eseguire un'attività all'interno dell'esecutore. Se un'attività viene inviata per l'esecuzione e il thread è attualmente impegnato nell'esecuzione di un'altra attività, l'attività attenderà in coda finché il thread non sarà libero di eseguirla.

Quando si esegue il programma sopra, il programma non verrà mai chiuso. Sarà necessario spegnerlo esplicitamente poiché il servizio esecutore continua ad ascoltare nuove attività.

Implementazioni Java ExecutorService

ExecutorService è molto simile a un pool di thread. In effetti, l'implementazione di ExecutorService nel java.util.concurrent pacchetto è un'implementazione del pool di thread. ExecutorService ha le seguenti implementazioni nel pacchetto java.util.concurrent:

ThreadPoolExecutor

ThreadPoolExecutor esegue le attività fornite utilizzando uno dei suoi thread in pool internamente.

Creazione di un 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 è un ExecutorService che può pianificare le attività da eseguire dopo un ritardo o da eseguire ripetutamente con un intervallo di tempo fisso tra ogni esecuzione.

Esempio

ScheduledExecutorService scheduledexecutorservice = Executors.newScheduledThreadPool (5) ScheduledFuture schedulatofuture = schedulatoExecutorService.schedule (new Callable () {public Object call () genera Eccezione {System.out.println ('eseguito') return 'called'}}, 5, TimeUnit. SECONDI)

ExecutorService Usage

Esistono diversi modi per delegare attività a un ExecutorService.

  • eseguire (eseguibile)

  • invia (eseguibile)

  • invokeAny ()

  • invokeAll ()

Esegui Runnable

Java ExecutorService execute (Runnable) accetta un oggetto java.lang.Runnable e lo esegue in modo asincrono.

ExecutorService executorService = Executors.newSingleThreadExecutor () executorService.execute (new Runnable () {public void run () {System.out.println ('asynchronous task')}}) executorService.shutdown ()

Non c'è modo di ottenere il risultato dell'esecuzione Runnable, per questo devi usare Callable.

Invia eseguibile

Il metodo di invio (Runnable) di Java ExecutorService accetta un'implementazione Runnable e restituisce un oggetto futuro. L'oggetto futuro può essere utilizzato per verificare se il Runnable ha terminato l'esecuzione.

Future future = executorService.submit (new Runnable () {public void run () {System.out.println (: asynchronous task ')}}) future.get () // restituisce null se l'attività è terminata correttamente.

Invia Callable

Il metodo submit (Callable) di Java ExecutorService è simile a submit (Runnable) ma accetta Java Callable invece di Runnable.

Futuro futuro = executorService.submit (new Callable () {public Object call () genera Eccezione {System.out.println ('Asynchronous callable') return 'Callable Result'}}) System.out.println ('future.get ( ) = 'future.get ())
 Produzione: Asynchroous callable future.get = Risultato richiamabile

invokeAny ()

Il metodo invokeAny () accetta una raccolta di oggetti Callable. Invocare questo metodo non restituisce alcun futuro, ma restituisce il risultato di uno degli oggetti Callable.

ExecutorService executorService = Executors.newSingleThreadExecutor () Setcallables = new HashSet() callables.add (new Callable () {public String call () genera l'eccezione {return'task A '}}) callables.add (new Callable () {public String call () throws Exception {return'task B'} }) callables.add (new Callable () {public String call () genera un'eccezione {return'task C '}}) String result = executorService.invokeAny (callables) System.out.println (' result = '+ result) executorService .spegnimento()

Quando esegui il codice precedente, il risultato cambia. Potrebbe essere Attività A, Attività B e così via.

InvokeAll ()

Il metodo invokeAll () richiama tutti gli oggetti Callable passati come parametri. Restituisce gli oggetti futuri che possono essere utilizzati per ottenere i risultati dell'esecuzione di ogni Callable.

ExecutorService executorService = Executors.newSingleThreadExecutor () Setcallables = new HashSet() callables.add (new Callable () {public String call () genera un'eccezione {return 'Task A'}}) callables.add (new Callable () {public String call () throws Exception {return 'Task B'} }) callables.add (new Callable () {public String call () genera eccezione {return 'Task C'}}) Listfutures = executorService.invokeAll (callables) for (Future future: futures) {System.out.println ('future.get =' + future.get ())} executorService.shutdown ()

Runnable vs Callable

Le interfacce eseguibili e richiamabili sono molto simili tra loro. La differenza è visibile nella dichiarazione del interfacce. Entrambe le interfacce rappresentano un'attività che può essere eseguita contemporaneamente da un thread o da ExecutorService.

Dichiarazione richiamabile:

interfaccia pubblica Callable {public object call () genera un'eccezione}

Dichiarazione eseguibile:

interfaccia pubblica eseguibile {public void run ()}

La differenza principale tra i due è che il metodo call () può restituire un oggetto dalla chiamata al metodo. E il metodo call () può lanciare un file mentre il metodo run () non può.

cosa fa .innerhtml

annulla attività

È possibile annullare l'attività inoltrata a ExecutorService semplicemente chiamando il metodo cancel sul futuro inoltrato quando l'attività viene inviata.

future.cancel ()

ExecutorService Shutdown

Per mantenere i thread in esecuzione anche dopo che l'esecuzione è stata completata, è necessario chiudere ExecutorService.

spegnimento()

Per terminare i thread all'interno di un ExecutorService puoi chiamare il metodo shutdown ().

executorService.shutdown ()

Questo ci porta alla fine di questo articolo in cui abbiamo appreso come utilizzare ExecutorService per eseguire attività in un thread. Spero che tu sia chiaro con tutto ciò che è stato condiviso con te in questo tutorial.

Se hai trovato pertinente questo articolo su 'ExecutorService in Java', controlla il file una società di formazione online affidabile con una rete di oltre 250.000 studenti soddisfatti sparsi in tutto il mondo.

Siamo qui per aiutarti in ogni fase del tuo viaggio e creare un curriculum progettato per studenti e professionisti che vogliono essere uno sviluppatore Java. Il corso è progettato per darti un vantaggio nella programmazione Java e formarti per concetti Java sia di base che avanzati insieme a vari piace Ibernazione & .

Se incontri delle domande, sentiti libero di porre tutte le tue domande nella sezione commenti di 'ExecutorService in Java' e il nostro team sarà lieto di rispondere.