concurrency java semaphore
Denne opplæringen vil diskutere komponenter i java.util.concurrent-pakken som Java Semaphore, Executor Framework, ExecutorService for å implementere Concurrency i Java:
Fra de forrige Java-opplæringene våre vet vi at Java-plattformen støtter samtidig programmering fra grunnen av. Den grunnleggende enheten for samtidighet er en tråd, og vi har diskutert tråder og multitråding i Java i detalj.
Fra Java 5 og utover ble en pakke kalt ‘java.util.concurrent’ lagt til Java-plattformen. Denne pakken inneholder et sett med klasser og biblioteker som gjør det lettere for programmereren å utvikle samtidige (flertrådede) applikasjoner. Ved å bruke denne pakken trenger vi ikke å skrive komplekse klasser, ettersom vi har klare implementeringer av de fleste samtidige konsepter.
=> Sjekk ALLE Java-opplæringsprogrammer her.
I denne opplæringen vil vi diskutere de forskjellige komponentene i pakken java.util.concurrent angående samtidighet og multitrading i Java.
Hva du vil lære:
java.util.conconurrent Package
Nedenfor er de forskjellige komponentene i java.util.concurrent-pakken angående samtidighet og multitrading i Java. La oss utforske hver komponent i detalj ved hjelp av enkle programmeringseksempler. Noen av komponentene vil vi
diskutere er:
- Utøvende rammeverk
- ExecutorService
- ThreadPool
- Kan kalles
- Låser - ReentrantLock
- Semafor
- ForkJoinPool
Executor Framework I Java
Executor Framework i Java ble utgitt med JDK 5-utgivelsen. Executor Framework (java.util.concurrent.Executor) er et rammeverk som består av komponenter som hjelper oss til effektivt å håndtere flere tråder.
Ved hjelp av Executor Framework kan vi kjøre objekter som kan kjøres ved å gjenbruke allerede eksisterende tråder. Vi trenger ikke lage nye tråder hver gang vi trenger å kjøre objekter.
Executor API skiller eller avkobler kjøringen av en oppgave fra den faktiske oppgaven ved hjelp av en Leder . En eksekutor er sentrert på Executor-grensesnittet og har undergrensesnitt, dvs. ExecutorService og klassen ThreadPoolExecutor.
Dermed bruker vi Executor, vi må bare lage Runnable objekter og deretter sende dem til eksekutoren som utfører dem.
Noen av de beste metodene som skal følges når du bruker Executor-rammeverket, er,
- Vi bør kryssjekke og planlegge en kode for å gjennomgå topplistene slik at vi kan oppdage fastlåst så vel som livelock i koden.
- Java-kode skal alltid utføres mot statiske analyseverktøy. Eksempler av statiske analyseverktøy er FindBugs og PMD.
- Vi bør ikke bare fange unntak, men også feilene i flertrådede programmer.
La oss nå diskutere komponentene i Executor Framework i Java.
Leder
Utføreren kan defineres som et grensesnitt som brukes til å representere et objekt som utfører oppgavene som er gitt til det. Hvorvidt oppgaven skal kjøres på nåværende eller ny tråd, avhenger av fra hvilket sted påkallelsen ble startet, noe som videre avhenger av implementeringen.
Så ved hjelp av Executor kan vi koble oppgavene fra selve oppgaven og deretter kjøre dem asynkront.
Imidlertid trenger ikke utførelsen av oppgaven med Executor være asynkron. Eksekutører kan også påkalle oppgaven umiddelbart ved å bruke påkallingstråd.
Nedenfor er et eksempel på en kode for å opprette Executor-forekomst:
public class Invoker implements Executor { @Override public void execute (Runnable r_interface) { r_interface.run(); } }
Når innkalleren er opprettet, som vist ovenfor, kan vi bruke den til å utføre oppgaven som følger.
public void execute () { Executor executor = new Invoker (); executor.execute ( () -> { //perform task }); }
Merk at hvis oppgaven ikke aksepteres av eksekutoren, kaster den RejectedExecutionException.
ExecutorService
En ExecutorService (java.util.concurrent.ExecutorService) planlegger de innsendte oppgavene i henhold til tilgjengeligheten av tråder og opprettholder også en minnekø. ExecutorService fungerer som en komplett løsning for asynkron behandling av oppgaver.
For å bruke ExecutorService i kode oppretter vi en Runnable-klasse. ExecutorService opprettholder en trådgruppe og tilordner også oppgavene til trådene. Oppgaver kan også stå i kø i tilfelle tråden ikke er tilgjengelig.
Nedenfor er et enkelt eksempel på ExecutorService.
import java.util.concurrent.*; public class Main { public static void main(String() args) { //create ExecutorService instance with 10 threads ExecutorService executor_Service = Executors.newFixedThreadPool(10); //assign the service to Runnable instance executor_Service.execute(new Runnable() { @Override public void run() { //print the message System.out.println('Simple Example of ExecutorService!!!'); } }); //shutdown executorService executor_Service.shutdown(); } }
Produksjon
I det ovennevnte programmet oppretter vi en enkel ExecutorService-forekomst med en trådpool som består av 10 tråder. Deretter tildeles den Runnable-forekomsten og utføres for å skrive ut meldingen ovenfor. Etter at meldingen er skrevet ut, blir ExecutorService slått av.
Trådbasseng
Et trådbasseng i Java er en gruppe arbeidertråder som kan brukes på nytt mange ganger og tildeles jobber.
Et trådbasseng inneholder en gruppe tråder med fast størrelse. Hver tråd blir trukket ut fra trådgruppen og tilordnet en oppgave av tjenesteleverandøren. Når den tildelte jobben er fullført, blir tråden gitt til trådgruppen igjen.
Trådbasseng er fordelaktig ettersom vi ikke trenger å opprette en ny tråd hver gang oppgaven er tilgjengelig, og ytelsen forbedres. Den brukes i sanntidsapplikasjoner som bruker Servlet og JSP hvor trådbassenger brukes til å behandle forespørsler.
I applikasjoner med flere tråder sparer trådbassenget ressurser og hjelper til med å holde parallelliteten innenfor forhåndsdefinerte grenser.
Java-programmet nedenfor demonstrerer trådbassenget i Java.
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class WorkerThreadClass implements Runnable { private String message; //thread class constructor public WorkerThreadClass(String s){ this.message=s; } //run method for thread public void run() { System.out.println(' Start: '+message); processmessage(); //sleep between start and end System.out.println(' End: '+ message); } //processmessage method => sleeps the thread for 2 sec private void processmessage() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } public class Main { public static void main(String() args) { //create a ExecutorService instance ExecutorService executor = Executors.newFixedThreadPool(5);//creating a pool of 5 threads //create thread instances and execute them for (int i = 0; i <5; i++) { Runnable workerThrd = new WorkerThreadClass('Thread_' + i); executor.execute(workerThrd);//calling execute method of ExecutorService } //shutdown ExecutorService executor.shutdown(); while (!executor.isTerminated()) { } System.out.println('Finished all threads'); } }
Produksjon
beste mp3 musikk nedlasting for pc
I de ovennevnte programmene er det en trådgruppe med 5 tråder som opprettes ved hjelp av 'newFixedThreadPool' -metoden. Deretter opprettes trådene og legges til i bassenget og tilordnes ExecutorService for utføring.
Kan kalles i Java
Vi vet allerede at vi kan lage tråder ved å bruke to tilnærminger. En tilnærming er å utvide trådklassen mens den andre tilnærmingen er å implementere et Runnable-grensesnitt.
Imidlertid mangler tråder opprettet ved hjelp av det Runnable-grensesnittet en funksjon, dvs. det gir ikke resultat når tråden avsluttes eller kjøres () fullfører kjøringen. Det er her det kallbare grensesnittet kommer inn i bildet.
Ved hjelp av et kallbart grensesnitt definerer vi en oppgave slik at den returnerer et resultat. Det kan også kaste et unntak. Det kallbare grensesnittet er en del av pakken java.util.concurrent.
Det kallbare grensesnittet gir en call () -metode som er på de samme linjene som run () -metoden som tilbys av det Runnable-grensesnittet, med den eneste forskjellen at call () -metoden returnerer en verdi og kaster avkrysset unntak.
Call () -metoden for Callable interface har følgende prototype.
public Object call () throws Exception;
Siden call () -metoden returnerer et objekt, må hovedtråden være klar over dette.
Derfor skal returverdien lagres i et annet objekt som er kjent for hovedtråden. Dette formålet betjenes ved å bruke et 'Future' -objekt. Et fremtidig objekt er et objekt som inneholder resultatet som returneres av en tråd. Eller med andre ord, det vil holde resultatet når Callable kommer tilbake.
Callable innkapsler en oppgave som skal kjøres på en annen tråd. Et fremtidig objekt lagrer resultatet returnert fra en annen tråd.
Et kallbart grensesnitt kan ikke brukes til å lage en tråd. Vi trenger Runnable for å lage en tråd. For å lagre resultatet kreves et fremtidig objekt. Java tilbyr en konkret type kalt “FutureTask” som kombinerer funksjonaliteten ved å implementere både Runnable og Future.
Vi lager en FutureTask ved å tilby en konstruktør Callable. Dette FutureTask-objektet blir deretter gitt til konstruktøren av Thread-klassen for å lage et Thread-objekt.
Nedenfor er et Java-program som demonstrerer Callable-grensesnittet og Future-objektet. Vi bruker også FutureTask-objektet i dette programmet.
Som allerede nevnt, i programmet oppretter vi en klasse som implementerer et kallbart grensesnitt med en overstyrt samtale () -metode. I hovedmetoden lager vi 10 FutureTask-objekter. Hver objektkonstruktør har et kallbart klasseobjekt som argument. Deretter er FutureTask-objektet knyttet til en trådforekomst.
Derfor oppretter vi indirekte en tråd ved hjelp av et kallbart grensesnittobjekt.
import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; //create a class implementing Callable interface class CallableDemo implements Callable { //define call () method public Object call() throws Exception { Random generator = new Random(); Integer randomNumber = generator.nextInt(10); Thread.sleep(randomNumber * 1000); return randomNumber; } } public class Main { public static void main(String() args) throws Exception { // Array of FutureTask objects FutureTask() randomNumberTasks = new FutureTask(10); for (int i = 0; i <10; i++) { Callable callable = new CallableDemo(); // Create the FutureTask with Callable class randomNumberTasks(i) = new FutureTask(callable); // create thread with FutureTask Thread t = new Thread(randomNumberTasks(i)); //start the thread t.start(); } System.out.println('The contents of FutureTask objects:'); for (int i = 0; i < 10; i++) { // get() contents of FutureTask System.out.print(randomNumberTasks(i).get() + ' '); } } }
Produksjon
Som vist i programmet ovenfor genererer call () -metoden for Callable som overstyres i klassen som implementerer Callable tilfeldige tall. Når tråden er startet, viser den disse tilfeldige tallene.
Vi bruker også FutureTask-objekter i hovedfunksjonen. Når det implementerer Future-grensesnittet, trenger vi ikke lagre resultatene i trådobjektene. På samme måte kan vi avbryte oppgaven, sjekke om den kjører eller fullføres, og også få resultatet ved hjelp av FutureTask-objektet.
ReentrantLock i Java
Vi har diskutert trådsynkronisering ved hjelp av det synkroniserte nøkkelordet i detalj i vår siste opplæring. Bruken av det synkroniserte ordet for trådsynkronisering er den grunnleggende metoden og er noe stiv.
Ved å bruke det synkroniserte nøkkelordet kan en tråd bare låses en gang. Etter at en tråd kommer ut av den synkroniserte blokken, tar neste tråd også låsen. Det er ingen ventekø. Disse problemene kan føre til sult i en annen tråd, da det kanskje ikke får tilgang til ressursene på lang tid.
For å løse disse problemene trenger vi en fleksibel metode for å synkronisere trådene. “Reentrant Locks” er denne metoden i Java som gir synkronisering med langt større fleksibilitet.
Klassen “ReentrantLock” implementerer Reentrant-låser og er en del av pakken “import java.util.concurrent.locks”. ReentrantLock-klassen gir metodesynkronisering for å få tilgang til delte ressurser. Klassene har også låsing og opplåsingsmetoder for å låse / låse opp ressurser når de er tilgjengelige med tråder.
En særegen egenskap ved ReentrantLock er at tråden kan låse den delte ressursen mer enn en gang ved hjelp av ReentrantLock. Det gir hold count som er satt til en når tråden låser ressursen.
Tråden kan gå inn på nytt og få tilgang til ressursen før den låses opp. Hver gang tråden får tilgang til ressursen ved hjelp av Reentrant-låsen, økes holdantallet med en. For hver opplåsing reduseres holdetallet med en.
Når antall hold når 0, blir den delte ressursen låst opp.
ReentrantLock-klassen gir også en rettferdighetsparameter som er en boolsk verdi som kan overføres med låsen. Når rettferdighetsparameteren er satt til sant, overføres låsen til den lengst ventende tråden når en tråd frigjør låsen. Dette forhindrer sult.
Reentrant-låsene kan brukes som følger:
return_type method_name() { reentrantlock.lock(); try { //Do some work } catch(Exception e) { e.printStackTrace(); } finally { reentrantlock.unlock(); } }
Merk at opplåsingserklæringen for ReentrantLock alltid er i den endelige blokken. Dette garanterer at låsen frigjøres selv om et unntak kastes.
La oss implementere et Java-program for å forstå ReentrantLock.
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.*; import java.util.concurrent.locks.ReentrantLock; //thread class that implements Runnable interface class ThreadClass implements Runnable { String task_name; //define ReentrantLock object ReentrantLock thrd_lck; //ThreadClass constructor initialized lock and task name public ThreadClass(ReentrantLock r_lock, String t_name) { thrd_lck = r_lock; task_name = t_name; } //thread run () method public void run() { boolean bool_val = false; while (!bool_val) { //check for Outer Lock boolean tryLock_val = thrd_lck.tryLock(); // if lock is free, do the following if(tryLock_val) { try { for(int i=0;i<=6;i++) { if(i>=2) { thrd_lck.lock(); Thread thread_one = new Thread(); System.out.println('Thread Created.....'); if(i==3) { thread_one.setName('Maint Thread2'); System.out.println('Thread Created.....'); } } if(i==4) thrd_lck.unlock(); break; } System.out.println('ReentrantLock=>Is locked after sleep(1500) : ' + thrd_lck.isLocked()); System.out.println('Work done for task : ' + task_name ); bool_val = true; } catch(Exception e) { e.printStackTrace(); } } } } } public class Main { public static void main(String() args) { //define ReentrantLock lock object and service pool ReentrantLock reentrant_lock = new ReentrantLock(); ExecutorService pool = Executors.newFixedThreadPool(2); //create thread instance and pass lock and task name Runnable worker_thread = new ThreadClass(reentrant_lock, 'ThreadJob'); //execute the thread in exec pool pool.execute(worker_thread); //shut down the pool pool.shutdown(); } }
Produksjon
I programmet ovenfor har vi opprettet en tråd og brukt ReentrantLock til den. Ved hjelp av ReentrantLock kan du få tilgang til den delte ressursen.
Semafor i Java
Den neste metoden for trådsynkronisering er å bruke Semaphore. Ved å bruke denne konstruksjonen kalt semafor, blir tilgang til en delt ressurs kontrollert gjennom en teller. Signaler sendes mellom trådene slik at vi kan beskytte den kritiske delen og også unngå tapte signaler.
En semafor kan defineres som en variabel som brukes til å administrere samtidige prosesser ved å synkronisere disse prosessene. Semaforer brukes også til å synkronisere tilgangen til den delte ressursen og derved unngå et løp. Tillatelsen gitt til en tråd for tilgang til den delte ressursen av semafor kalles også tillatelse.
Avhengig av hvilke funksjoner de utfører, kan semaforer deles inn i to typer:
# 1) Binær semafor: En binær semafor brukes til å synkronisere samtidige prosesser og implementere gjensidig ekskludering. En binær semafor antar bare to verdier, dvs. 0 og 1.
# 2) Counting Semaphore: Den tellende semaforen har en verdi som indikerer antall prosesser som kan komme inn i den kritiske delen. Når som helst angir verdien det maksimale antall prosesser som kommer inn i den kritiske delen.
Så hvordan fungerer en semafor?
Arbeidet til en semafor kan oppsummeres i følgende trinn:
- Hvis semafor teller> 0, betyr det at tråden har tillatelse til å få tilgang til kritisk seksjon, og da blir tellingen redusert.
- Ellers er tråden blokkert til tillatelsen er anskaffet.
- Når tråden er ferdig med tilgang til den delte ressursen, frigjøres tillatelsen og semafortellingen økes slik at en annen tråd kan gjenta trinnene ovenfor og få tillatelsen.
Ovennevnte trinn for bearbeiding av semaforer kan oppsummeres i flytskjemaet nedenfor.
hvilke programmer som kan redigere pdf-filer
I Java trenger vi ikke implementere semaforen vår, men den gir en Semafor klasse som implementerer semaforefunksjonaliteten. Semaphore-klassen er en del av java.util.concurrent pakke.
Semaforeklassen gir følgende konstruktører som vi kan lage semaforobjekt med:
Semaphore (int num_value) Semaphore (int num_value, boolean how)
Her,
num_value => opprinnelig verdi av tillatelsestellingen som bestemmer antall tråder som kan få tilgang til den delte ressursen.
hvordan => angir rekkefølgen som trådene får tillatelse (hvor = sant). Hvis hvordan = falsk, følges ingen slik ordre.
Nå skal vi implementere et Java-program som skal demonstrere Semaphore som brukes til å administrere tilgangen til delt ressurs og forhindre løpetilstanden.
import java.util.concurrent.*; //class for shared resource class SharedRes { static int count = 0; } class ThreadClass extends Thread { Semaphore sem; String threadName; public ThreadClass(Semaphore sem, String threadName) { super(threadName); this.sem = sem; this.threadName = threadName; } @Override public void run() { // Thread T1 processing if(this.getName().equals('T1')) { System.out.println('Start: ' + threadName); try { System.out.println(threadName + ' :waiting for a permit.'); // acquire the permit sem.acquire(); System.out.println(threadName + ':Acquired permit'); // access shared resource for(int i=0; i <5; i++) { SharedRes.count++; System.out.println(threadName + ': ' + SharedRes.count); Thread.sleep(10); } } catch (InterruptedException exc) { System.out.println(exc); } // Release the permit. System.out.println(threadName + ':Released the permit'); sem.release(); } // Thread T2 processing else { System.out.println('Start: ' + threadName); try { System.out.println(threadName + ':waiting for a permit.'); // acquire the lock sem.acquire(); System.out.println(threadName + ':Acquired permit'); // process the shared resource for(int i=0; i < 5; i++) { SharedRes.count--; System.out.println(threadName + ': ' + SharedRes.count); Thread.sleep(10); } } catch (InterruptedException exc) { System.out.println(exc); } // Release the permit. System.out.println(threadName + ':Released the permit.'); sem.release(); } } } public class Main { public static void main(String args()) throws InterruptedException { //create Semaphore=> #permits = 1 Semaphore sem = new Semaphore(1); // Create thread instances T1 & T2 //T1=> Increments the count; T2=> Decrements the count ThreadClass thread1 = new ThreadClass(sem, 'T1'); ThreadClass thread2 = new ThreadClass(sem, 'T2'); // start T1 & T2 thread1.start(); thread2.start(); // Wait T1 & T2 thread1.join(); thread2.join(); System.out.println('count: ' + SharedRes.count); // display final count. } }
Produksjon
Dette programmet erklærte en klasse for den delte ressursen. Det erklærer også en trådklasse der vi har en semaforvariabel som er initialisert i klassekonstruktøren.
I den overstyrte run () -metoden i Thread-klassen utføres behandling av trådforekomsten der tråden skaffer tillatelsen, får tilgang til en delt ressurs og deretter frigjør tillatelsen.
I hovedmetoden erklærte vi to trådforekomster. Begge trådene startes, og deretter venter de ved å bli med-metoden. Til slutt vises tellingen, dvs. 0 som indikerer at begge trådene er ferdige med den delte ressursen.
Gaffel og delta i Java
Forg / join-rammeverket ble først introdusert i Java 7. Dette rammeverket består av verktøy som kan øke hastigheten på parallell behandling. Den bruker alle tilgjengelige prosessorkjerner i systemet og fullfører oppgaven. Gaffel / join-rammeverket bruker skillet og erobre tilnærmingen.
Den grunnleggende ideen bak Fork / Join-rammeverket er at det første rammeverket “Forks”, dvs. rekursivt bryter oppgaven i mindre individuelle deloppgaver til oppgavene er atomiske slik at de kan utføres asynkront.
Etter å ha gjort dette blir oppgavene 'sammenføyd', dvs. at alle underoppgaver blir sammenføyet rekursivt til en enkelt oppgave eller returverdi.
Gaffel / join-rammeverket har en gruppe tråder kjent som “ForkJoinPool”. Dette bassenget administrerer 'ForkJoinWorkerThread' -typen av arbeidertråder og gir dermed effektiv parallellbehandling.
ForkJoinPool administrerer arbeidertråder og hjelper oss også med å få informasjon om ytelse og tilstand for trådbassenget. ForkJoinPool er en implementering av 'ExecutorService' vi diskuterte ovenfor.
I motsetning til arbeidertråder oppretter ForkJoinPool ikke en egen tråd for hver deloppgave. Hver tråd i ForkJoinPool opprettholder sin deque (dobbeltkølet) for å lagre oppgaver.
Dekken fungerer som trådens balansering av arbeidsbelastning og gjør dette ved hjelp av en 'arbeidsstealing-algoritme' som er beskrevet nedenfor.
Arbeids stjele algoritme
Vi kan definere den arbeidsstyrealgoritmen i enkle ord som 'Hvis en tråd er ledig,' stjeler 'arbeidet fra travle tråder'.
En arbeidertråd vil alltid få oppgavene fra deque. Når alle oppgavene i deken er oppbrukt og deken er tom, vil arbeidertråden ta en oppgave fra halen til en annen deque eller fra 'global entry queue'.
På denne måten blir muligheten for at tråder som konkurrerer om oppgaver minimert, og også antallet ganger tråden må speide etter arbeid reduseres. Dette er fordi tråden allerede har fått den største delen av tilgjengelig arbeid og er ferdig med den.
Så hvordan kan vi bruke ForkJoinPool i et program?
Den generelle definisjonen av ForkJoinPool er som følger:
public class ForkJoinPool extends AbstractExecutorService
Klassen ForkJoinPool er en del av pakken “java.util.concurrent”.
I Java 8 oppretter vi en forekomst av ForkJoinPool ved hjelp av den statiske metoden 'common-pool ()' som gir en referanse til den felles poolen eller standard thread pool.
ForkJoinPool commonPool = ForkJoinPool.commonPool ();
I Java 7 oppretter vi en ForkJoinPool-forekomst og tildeler den til feltet for verktøyklasse som vist nedenfor.
public static ForkJoinPool forkJoinPool = new ForkJoinPool(2);
Ovennevnte definisjon indikerer at bassenget har et parallellitetsnivå på 2 slik at bassenget vil bruke to prosessorkjerner.
For å få tilgang til bassenget ovenfor, kan vi gi følgende uttalelse.
ForkJoinPool forkJoinPool = PoolUtil.forkJoinPool;
Basistypen for ForkJoinPool-oppgaver er “ForkJoinTask”. Vi bør utvide en av underklassene, dvs. for ugyldige oppgaver, RecursiveAction og for oppgaver som returnerer en verdi, RecursiveTask. Begge de utvidede klassene gir en abstrakt metodeberegning () der vi definerer oppgavens logikk.
Nedenfor er et eksempel for å demonstrere ForkJoinPool.
import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; //class declaration for ForkJoinPool tasks class FJPoolTask extends RecursiveAction { private long Load = 0; public FJPoolTask(long Load) { this.Load = Load; } @Override protected void compute() { //if threshold is reached, break tasks into smaller tasks List subtasks = new ArrayList(); subtasks.addAll(createSubtasks()); for(RecursiveAction subtask : subtasks){ subtask.fork(); } } //create subtasks private List createSubtasks() { List sub_tasks =new ArrayList(); FJPoolTask sub_task1 = new FJPoolTask(this.Load / 2); FJPoolTask sub_task2 = new FJPoolTask(this.Load / 2); FJPoolTask sub_task3 = new FJPoolTask(this.Load / 2); sub_tasks.add(sub_task1); sub_tasks.add(sub_task2); sub_tasks.add(sub_task3); return sub_tasks; } } public class Main { public static void main(final String() arguments) throws InterruptedException { //get count of available processors int proc = Runtime.getRuntime().availableProcessors(); System.out.println('Processors available:' +proc); //declare forkJoinPool ForkJoinPool Pool = ForkJoinPool.commonPool(); System.out.println(' Active Threads (Before invoke):' +Pool.getActiveThreadCount()); //Declare ForkJoinPool task object FJPoolTask t = new FJPoolTask(400); //submit the tasks to the pool Pool.invoke(t); System.out.println(' Active Threads (after invoke):' +Pool.getActiveThreadCount()); System.out.println('Common Pool Size :' +Pool.getPoolSize()); } }
Produksjon
I programmet ovenfor finner vi antall aktive tråder i systemet før og etter å ha kalt “påkalle ()” -metoden. Invoke () -metoden brukes til å sende oppgavene til bassenget. Vi finner også antall tilgjengelige prosessorkjerner i systemet.
ofte stilte spørsmål
Q # 1) Hva er Java Util Concurrent?
Svar: Pakken “java.util.concurrent” er et sett med klasser og grensesnitt som tilbys av Java for å lette utviklingen av samtidige (flertrådede) applikasjoner. Ved hjelp av denne pakken kan vi bruke grensesnittet og klassene samt API-er direkte uten å måtte skrive klassene våre.
Q # 2) Hvilket av følgende er samtidige implementeringer som er til stede i java.util. samtidig pakke?
Svar: På høyt nivå inneholder pakken java.util.concurrent verktøy som Executors, Synchronizers, Queues, Timings og Concurrent Collections.
hvordan åpne apk filer på windows
Q # 3) Hva er Future Java?
Svar: Et fremtidig objekt (java.util.concurrent.Future) brukes til å lagre resultatet som returneres av en tråd når det kallbare grensesnittet er implementert.
Q # 4) Hva er trådsikkert i Java?
Svar: En trådsikker kode eller klasse i Java er en kode eller klasse som kan deles i et flertrådet eller samtidig miljø uten problemer og gir forventede resultater.
Q # 5) Hva er den synkroniserte samlingen i Java?
Svar: En synkronisert samling er en trådsikker samling. Metoden synkronisert samling () av klassen java.util.Collections returnerer en synkronisert (trådsikker) samling.
Konklusjon
Med denne opplæringen har vi fullført temaet multi-threading og samtidighet i Java. Vi har diskutert multitrading i detalj i våre tidligere opplæringsprogrammer. Her diskuterte vi samtidigheten og implementeringen relatert til samtidighet og multitrading som er en del av java.util.concurrent-pakken.
Vi diskuterte to synkroniseringsmetoder til, semaforer og ReentrantLock. Vi diskuterte også ForkJoinPool som brukes til å utføre oppgavene ved å dele dem opp i enklere oppgaver og deretter til slutt bli med på resultatet.
Pakken java.util.concurrent støtter også rammeverket for utførere og utførere som hjelper oss med å utføre tråder. Vi diskuterte også implementering av trådbasseng som består av gjenbrukbare tråder som returneres til bassenget når kjøringen er ferdig.
Vi diskuterte et annet grensesnitt som ligner på Runnable, som også hjelper oss med å returnere et resultat fra tråden og Future-objektet som brukes til å lagre det oppnådde tråden.
=> Se opp den enkle Java-treningsserien her.
Anbefalt lesing
- Thread.Sleep () - Tråd Sleep () Metode i Java med eksempler
- Java-distribusjon: Opprettelse og utføring av Java JAR-fil
- Java Basics: Java Syntax, Java Class og Core Java Concepts
- Java Virtual Machine: Hvordan JVM hjelper med å kjøre Java-applikasjoner
- Få tilgang til modifikatorer i Java - opplæring med eksempler
- Java Synchronized: Hva er trådsynkronisering i Java
- JAVA-opplæring for nybegynnere: 100+ praktiske Java-videoveiledninger
- Java Integer og Java BigInteger Class med eksempler