Wat is ExecutorService in Java en hoe kan het worden gemaakt?



Dit artikel behandelt het concept van Executor-subinterface ExecutorService in Java met verschillende voorbeelden om het maken en beheren van threads in Java uit te leggen.

Java-programmeertaal werkt erg efficiënt met toepassingen die vereisen dat de taken gelijktijdig in een thread worden uitgevoerd. Het wordt voor elke toepassing moeilijk om een ​​groot aantal threads tegelijkertijd uit te voeren. Dus om dit probleem op te lossen, wordt geleverd met ExecutorService, een subinterface van de . In dit artikel bespreken we de functionaliteit van ExecutorService in Java. Hieronder volgen de onderwerpen die in deze blog worden behandeld:

Wat is Executor Framework?

Het is vrij gemakkelijker om een ​​of twee threads tegelijkertijd te maken en uit te voeren. Maar het wordt moeilijk wanneer het aantal threads toeneemt tot een aanzienlijk aantal. Bij grote multi-threaded applicaties worden honderden threads tegelijk uitgevoerd. Daarom is het volkomen logisch om het maken van threads te scheiden van het threadbeheer in een applicatie.





De uitvoerder is een helpt u bij het maken en beheren van threads in een applicatie. De helpt u bij de volgende taken.

  • Thread Creation: het biedt een verscheidenheid aan methoden voor het maken van threads die helpen bij het gelijktijdig uitvoeren van uw applicaties.



  • Draadbeheer: het beheert ook de levenscyclus van de draad. U hoeft zich geen zorgen te maken of de thread actief, bezet of dood is voordat u de taak verzendt voor uitvoering.

  • Taakverzending en uitvoering: Executor-framework biedt methoden voor taakverzending in de threadpool, het geeft ook de macht om te beslissen of de thread wordt uitgevoerd of niet.

executorservice-executorservice in java -edureka

ExecutorService in Java-voorbeeld

Het is een subinterface van het executor-framework dat bepaalde functionaliteiten toevoegt om de threadlevenscyclus van een applicatie te beheren. Het biedt ook een submit () methode die zowel uitvoerbaar als opvraagbaar kan zijn voorwerpen.



In het volgende voorbeeld zullen we een ExecutorService maken met een enkele thread en vervolgens de taak indienen die binnen de thread moet worden uitgevoerd.

import java.util.concurrent.ExecutorService import java.util.concurrent.Executors public class Voorbeeld {public static void main (String [] args) {System.out.println ('Inside:' + Thread.currentThread (). getName ( )) System.out.println ('create ExecutorService') ExecutorService executorservice = Executors.newSingleThreadExecutor () System.out.println ('een uitvoerbaar maken') Runnable runnable = () -> {System.out.println ('inside: '+ Thread.currentThread (). GetName ())} System.out.println (' dien de taak gespecificeerd door de uitvoerder in bij de uitvoerder ') executorservice.submit (uitvoerbaar)}}
 Uitgang: Inside: hoofd maken van ExecutorService het maken van een uitvoerbare taak dien de taak gespecificeerd door de uitvoerbaar in bij de uitvoerderenservice binnen: pool-1-thread-1

Bovenstaande laat zien hoe we een ExecutorService kunnen maken en een taak binnen de executor kunnen uitvoeren. Als een taak wordt verzonden voor uitvoering en de thread is momenteel bezig met het uitvoeren van een andere taak, dan zal de taak in een wachtrij wachten totdat de thread vrij is om deze uit te voeren.

Als u het bovenstaande programma uitvoert, wordt het programma nooit afgesloten. U moet het expliciet afsluiten omdat de executor-service blijft luisteren naar nieuwe taken.

Implementaties van Java ExecutorService

ExecutorService lijkt veel op een threadpool. In feite is de implementatie van de ExecutorService in het bestand java.util.concurrent pakket is een threadpool-implementatie. De ExecutorService heeft de volgende implementaties in het pakket java.util.concurrent:

ThreadPoolExecutor

De ThreadPoolExecutor voert de gegeven taken uit met behulp van een van zijn intern gepoolde threads.

Een threadPoolExecutor maken

int corePoolSize = 5 int maxPoolSize = 10 lang keepAliveTime = 5000 ExecutorService threadPoolExecutor = nieuwe threadPoolExecutor (corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, nieuwe LinkedBlockingQueue ())

ScheduledThreadPoolExecutor

De java.util.concurrent.ScheduledThreadPoolExecutor is een ExecutorService die taken kan plannen om na een vertraging uit te voeren of om herhaaldelijk uit te voeren met een vast tijdsinterval tussen elke uitvoering.

Voorbeeld

ScheduledExecutorService scheduledexecutorservice = Executors.newScheduledThreadPool (5) ScheduledFuture geplandfuture = geplandExecutorService.schedule (new Callable () {openbare objectaanroep () genereert Uitzondering {System.out.println ('uitgevoerd') retour 'genaamd'}}, 5, TimeUnit. SECONDEN)

ExecutorService-gebruik

Er zijn een paar verschillende manieren om taken aan een ExecutorService te delegeren.

  • uitvoeren (uitvoerbaar)

  • indienen (Runnable)

  • invokeAny ()

  • invokeAll ()

Voer Runnable uit

Java ExecutorService execute (Runnable) neemt een java.lang.Runnable-object en voert het asynchroon uit.

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

Er is geen manier om het resultaat van de uitvoering Runnable te krijgen, daarvoor moet je de Callable gebruiken.

Dien Runnable in

Java ExecutorService submit (Runnable) methode neemt een Runnable-implementatie en retourneert een toekomstig object. Het toekomstige object kan worden gebruikt om te controleren of de uitvoering van de Runnable is voltooid.

Future future = executorService.submit (new Runnable () {public void run () {System.out.println (: asynchrone taak ')}}) future.get () // retourneert null als de taak correct is voltooid.

Dien Callable in

De Java ExecutorService submit (Callable) methode is vergelijkbaar met submit (Runnable) maar hiervoor is Java Callable nodig in plaats van Runnable.

Future future = executorService.submit (new Callable () {public Object call () genereert uitzondering {System.out.println ('Asynchronous callable') return 'Callable Result'}}) System.out.println ('future.get ( ) = 'future.get ())
 Uitgang: Asynchroous callable future.get = Callable resultaat

invokeAny ()

De methode invokeAny () heeft een verzameling oproepbare objecten nodig. Het aanroepen van deze methode levert geen toekomst op, maar retourneert het resultaat van een van de opvraagbare objecten.

ExecutorService executorService = Executors.newSingleThreadExecutor () Setcallables = nieuwe HashSet() callables.add (new Callable () {public String call () gooit uitzondering {return'task A '}}) callables.add (new Callable () {public String call () gooit uitzondering {return'task B'} }) callables.add (new Callable () {public String call () gooit uitzondering {return'task C '}}) String resultaat = executorService.invokeAny (callables) System.out.println (' result = '+ resultaat) executorService .stilgelegd()

Als u de bovenstaande code uitvoert, verandert het resultaat. Het kan taak A, taak B enzovoort zijn.

InvokeAll ()

De methode invokeAll () roept alle oproepbare objecten aan die als parameters zijn doorgegeven. Het retourneert de toekomstige objecten die kunnen worden gebruikt om de resultaten van de uitvoering van elke oproepbare te krijgen.

ExecutorService executorService = Executors.newSingleThreadExecutor () Setcallables = nieuwe HashSet() callables.add (new Callable () {public String call () gooit uitzondering {return 'Task A'}}) callables.add (new Callable () {public String call () gooit uitzondering {return 'Task B'} }) callables.add (new Callable () {public String call () gooit Uitzondering {return 'Task C'}}) Lijstfutures = executorService.invokeAll (callables) voor (Future future: futures) {System.out.println ('future.get =' + future.get ())} executorService.shutdown ()

Runnable versus opvraagbaar

De uitvoerbare en oproepbare interfaces lijken erg op elkaar. Het verschil is zichtbaar in de aangifte van de interfaces. Beide interfaces vertegenwoordigen een taak die gelijktijdig kan worden uitgevoerd door een thread of ExecutorService.

Oproepbare verklaring:

openbare interface Oproepbaar {openbaar object call () genereert uitzondering}

Runnable-verklaring:

openbare interface Runnable {public void run ()}

Het belangrijkste verschil tussen de twee is dat de methode call () een object van de methodeaanroep kan retourneren. En de methode call () kan een while run () methode kan niet.

statische lidfunctie in c ++

taak annuleren

U kunt de taak die naar ExecutorService is verzonden, annuleren door simpelweg de annuleringsmethode aan te roepen voor de toekomst die wordt verzonden wanneer de taak wordt verzonden.

future.cancel ()

ExecutorService afsluiten

Om te voorkomen dat de threads worden uitgevoerd, zelfs nadat de uitvoering is voltooid, moet u de ExecutorService afsluiten.

stilgelegd()

Om de threads binnen een ExecutorService te beëindigen, kunt u de methode shutdown () aanroepen.

executorService.shutdown ()

Dit brengt ons bij het einde van dit artikel waar we hebben geleerd hoe we ExecutorService kunnen gebruiken om taken in een thread uit te voeren. Ik hoop dat je duidelijk bent met alles wat in deze tutorial met je is gedeeld.

Als u dit artikel over “ExecutorService in Java” relevant vond, bekijk dan het een vertrouwd online leerbedrijf met een netwerk van meer dan 250.000 tevreden leerlingen verspreid over de hele wereld.

We zijn hier om je te helpen bij elke stap op je reis en om een ​​curriculum te bedenken dat is ontworpen voor studenten en professionals die een Java-ontwikkelaar willen worden. De cursus is bedoeld om u een voorsprong te geven in het programmeren van Java en u te trainen in zowel kern- als geavanceerde Java-concepten, samen met verschillende Leuk vinden Slaapstand & .

Mocht u nog vragen tegenkomen, stel dan gerust al uw vragen in het commentaargedeelte van “ExecutorService in Java” en ons team zal u graag antwoorden.