concurrency java semaphore
Ovaj će vodič raspravljati o komponentama paketa java.util.concurrent poput Java Semaphore, Executor Framework, ExecutorService za implementaciju Concurrencya u Javi:
Iz naših prethodnih Java tutorijala znamo da Java platforma podržava istodobno programiranje od temelja. Osnovna jedinica istodobnosti je nit, a mi smo detaljno razgovarali o nitima i multithreadingu u Javi.
Od Jave 5 nadalje, paket nazvan ‘java.util.concurrent’ dodan je na Java platformu. Ovaj paket sadrži skup klasa i knjižnica što programeru olakšava razvoj istodobnih (višenitnih) aplikacija. Koristeći ovaj paket, ne moramo pisati složene klase jer imamo spremne implementacije većine istodobnih koncepata.
=> Ovdje provjerite SVE Java tutorijale.
U ovom uputstvu raspravit ćemo o različitim komponentama paketa java.util.concurrent koje se tiču istodobnosti i višestrukosti u Javi.
Što ćete naučiti:
java.util.concurrent paket
U nastavku su navedene razne komponente paketa java.util.concurrent koje se odnose na istodobnost i višestruko obrađivanje podataka u Javi. Istražimo pojedinosti svake komponente uz pomoć jednostavnih primjera programiranja. Neke od komponenata ćemo
raspravljati su:
- Okvir izvršitelja
- ExecutorService
- ThreadPool
- Pozivno
- Brave- ReentrantLock
- Semafor
- ForkJoinPool
Izvršni okvir u Javi
Izvršni okvir u Javi objavljen je izdanjem JDK 5. Okvir izvršitelja (java.util.concurrent.Executor) je okvir koji se sastoji od komponenata koje nam pomažu u učinkovitom rukovanju s više niti.
Korištenjem izvršnog okvira možemo pokretati objekte koji se mogu izvoditi ponovnom upotrebom već postojećih niti. Ne trebamo stvarati nove niti svaki put kada moramo pokretati objekte.
Izvršni API razdvaja ili razdvaja izvršenje zadatka od stvarnog zadatka pomoću Izvršitelj . Izvršitelj je usredotočen na sučelje izvršitelja i ima podsučelja, tj. ExecutorService i razred ThreadPoolExeecuter.
Stoga pomoću Executor-a jednostavno moramo stvoriti Runnable objekte i poslati ih izvršitelju koji ih izvršava.
Neke od najboljih praksi kojih se treba pridržavati tijekom korištenja okvira Executor su,
- Trebali bismo provjeriti i planirati kod za pregled najboljih popisa kako bismo mogli otkriti mrtvu točku kao i zaostatak u kodu.
- Java kôd uvijek treba izvoditi protiv alata za statičku analizu. Primjeri alati za statičku analizu su FindBugs i PMD.
- Ne bismo trebali uhvatiti samo iznimke, već i pogreške u programima s više niti.
Sada razgovarajmo o komponentama programa Executor Framework u Javi.
Izvršitelj
Izvršitelj se može definirati kao sučelje koje se koristi za predstavljanje objekta koji izvršava zadatke koji su mu dostavljeni. Hoće li se zadatak izvoditi na trenutnoj ili novoj niti ovisi o točki odakle je iniciranje pokrenuto, što dalje ovisi o implementaciji.
Dakle, pomoću programa Executor možemo razdvojiti zadatke od stvarnog zadatka, a zatim ih asinkrono pokrenuti.
Međutim, izvršavanje zadatka pomoću izvršnika ne mora biti asinkrono. Izvršitelji također mogu odmah pozvati zadatak pomoću niti za dozivanje.
Dolje je dat primjer koda za stvaranje egzekutorske instance:
public class Invoker implements Executor { @Override public void execute (Runnable r_interface) { r_interface.run(); } }
Jednom kada se pozivač stvori, kao što je gore prikazano, možemo ga koristiti za izvršavanje zadatka na sljedeći način.
public void execute () { Executor executor = new Invoker (); executor.execute ( () -> { //perform task }); }
Imajte na umu da ako izvršitelj ne prihvati zadatak, on baca RejectedExecutionException.
ExecutorService
ExecutorService (java.util.concurrent.ExecutorService) raspoređuje predane zadatke prema dostupnosti niti, a također održava memorijski red. ExecutorService djeluje kao cjelovito rješenje za asinkronu obradu zadataka.
Da bismo koristili ExecutorService u kodu, kreiramo klasu Runnable. ExecutorService održava spremište niti i također dodjeljuje zadatke nitima. Zadaci se također mogu staviti u red čekanja ako nit nije dostupan.
Dolje je dat jednostavan primjer ExecutorService.
kako reproducirati .swf datoteke
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(); } }
Izlaz
U gornjem programu kreiramo jednostavnu instancu ExecutorService s bazenom niti koji se sastoji od 10 niti. Zatim se dodjeljuje instanci Runnable i izvršava za ispis gornje poruke. Nakon ispisa poruke, ExecutorService se isključuje.
Bazen niti
Skup tema u Javi je skupina radničkih niti koje se mogu ponovno koristiti više puta i dodijeliti im poslove.
Skup tema sadrži skup niti fiksne veličine. Svaka nit izvlači se iz spremišta niti i pružatelj usluge joj dodjeljuje zadatak. Kada je dodijeljeni posao dovršen, nit se ponovno daje spremištu niti.
Spremište niti je povoljno jer ne moramo stvarati novu nit svaki put kada je zadatak dostupan, čime se poboljšava izvedba. Koristi se u aplikacijama u stvarnom vremenu koje koriste Servlet i JSP gdje se spremišta niti koriste za obradu zahtjeva.
U aplikacijama s više niti, Thread Pool štedi resurse i pomaže zadržati paralelizam unutar unaprijed definiranih granica.
Ispod navedeni Java program prikazuje spremište niti u Javi.
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'); } }
Izlaz
U gornjim programima postoji spremište niti od 5 niti koje su stvorene metodom 'newFixedThreadPool'. Zatim se niti kreiraju i dodaju u spremište i dodjeljuju izvršnoj službi za izvršenje.
Dozivno u Javi
Već znamo da možemo stvarati niti koristeći dva pristupa. Jedan je pristup proširivanjem klase Thread, dok je drugi pristup implementacijom Runnable sučelja.
Međutim, niti stvorene pomoću Runnable sučelja nemaju jednu značajku, tj. Ne vraća rezultat kada je nit završena ili run () dovršava izvršenje. Tu dolazi do izražaja sučelje Callable.
Korištenjem sučelja Callable definiramo zadatak tako da vraća rezultat. To također može donijeti iznimku. Sučelje koje se može pozvati dio je java.util.concurrent paketa.
Sučelje Callable pruža call () metodu koja se nalazi na sličnim linijama kao i run () metoda koju pruža Runnable sučelje s jedinom razlikom što call () metoda vraća vrijednost i baca provjerenu iznimku.
Metoda call () Callable sučelja ima sljedeći prototip.
public Object call () throws Exception;
Budući da metoda call () vraća objekt, glavna nit mora toga biti svjesna.
Stoga bi povratna vrijednost trebala biti pohranjena u drugom objektu koji je poznat glavnoj niti. U tu svrhu služi se objektom „Budućnost“. Budući objekt je objekt koji sadrži rezultat vraćen niti. Ili drugim riječima, zadržat će rezultat kad se Callable vrati.
Callable enkapsulira zadatak koji bi se trebao izvoditi na drugoj niti. Objekt Budućnost pohranjuje rezultat vraćen iz druge niti.
Sučelje koje se može pozvati ne može se koristiti za stvaranje niti. Za stvaranje niti trebamo Runnable. Tada je za spremanje rezultata potreban objekt Budućnosti. Java nudi konkretni tip nazvan 'FutureTask' koji kombinira funkcionalnost implementirajući i Runnable i Future.
Stvaramo FutureTask pružajući konstruktoru Callable. Ovaj se objekt FutureTask zatim daje konstruktoru klase Thread da stvori objekt Thread.
Dolje je dan Java program koji prikazuje sučelje koje se može pozvati i objekt Budućnost. U ovom programu koristimo i objekt FutureTask.
Kao što je već spomenuto, u programu kreiramo klasu koja implementira Callable sučelje s nadjačanom call () metodom. U glavnoj metodi kreiramo 10 objekata FutureTask. Svaki konstruktor objekta ima za objekt svoj objekt Callable class. Tada je objekt FutureTask povezan s instancom niti.
Stoga neizravno stvaramo nit koristeći objekt sučelja Callable.
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() + ' '); } } }
Izlaz
Kao što je prikazano u gornjem programu, call () metoda Callable koja je poništena u klasi koja implementira Callable generira slučajne brojeve. Nakon pokretanja niti, prikazuje te slučajne brojeve.
Također, u glavnoj funkciji koristimo objekte FutureTask. Kako implementira sučelje Budućnost, ne trebamo pohranjivati rezultate u objekte Thread. Slično tome, možemo otkazati zadatak, provjeriti je li pokrenut ili dovršen, a također dobiti rezultat pomoću objekta FutureTask.
kako napraviti vlastiti vatrozid
ReentrantLock u Javi
U posljednjem smo vodiču detaljno razgovarali o sinkronizaciji niti koristeći sinkroniziranu ključnu riječ. Upotreba sinkronizirane riječi za sinkronizaciju niti osnovna je metoda i donekle je kruta.
Pomoću sinkronizirane ključne riječi nit se može zaključati samo jednom. Također, nakon što jedna nit izađe iz sinkroniziranog bloka, sljedeća nit uzima zaključavanje. Nema reda čekanja. Ovi problemi mogu uzrokovati izgladnjivanje neke druge niti, jer dulje vrijeme možda neće moći pristupiti resursima.
Da bismo riješili ove probleme, potrebna nam je fleksibilna metoda sinkronizacije niti. 'Reentrant Locks' je ova metoda u Javi koja pruža sinkronizaciju s daleko većom fleksibilnošću.
Klasa 'ReentrantLock' implementira Reentrant brave i dio je paketa 'import java.util.concurrent.locks'. Klasa ReentrantLock omogućuje sinkronizaciju metode za pristup zajedničkim resursima. Klase također imaju metode zaključavanja i otključavanja za zaključavanje / otključavanje resursa kada im se pristupa nitima.
Jedna je osobitost ReentrantLock-a da nit može više puta zaključati zajednički resurs pomoću ReentrantLock-a. Pruža broj zadržavanja koji je postavljen na jedan kada nit zaključa resurs.
Nit može ponovno ući i pristupiti resursu prije otključavanja. Svaki put kad nit pristupi resursu pomoću zaključavanja Reentrant, broj zadržavanja povećava se za jedan. Za svako otključavanje, broj zadržavanja smanjuje se za jedan.
Kada broj zadržavanja dosegne 0, zajednički se resurs otključava.
Klasa ReentrantLock također pruža parametar pravičnosti koji je logička vrijednost koja se može proslijediti s konstruktorom brave. Kada se parametar poštenosti postavi na true, onda kad god jedna nit otpusti bravu, zaključavanje se prosljeđuje niti koja najduže čeka. To sprječava gladovanje.
Brave Reentrant mogu se koristiti na sljedeći način:
return_type method_name() { reentrantlock.lock(); try { //Do some work } catch(Exception e) { e.printStackTrace(); } finally { reentrantlock.unlock(); } }
Imajte na umu da je izjava za otključavanje za ReentrantLock uvijek u napokon bloku. To jamči oslobađanje brave čak i ako se izuzme izuzetak.
Primijenimo Java program da bismo razumjeli 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(); } }
Izlaz
U gore navedenom programu stvorili smo nit i za nju koristili ReentrantLock. Korištenjem ReentrantLock-a može se pristupiti zajedničkom resursu.
Semafor u Javi
Sljedeća metoda sinkronizacije niti je pomoću Semaphore. Korištenjem ove konstrukcije koja se naziva semafor, pristup dijeljenom resursu kontrolira se putem brojača. Signali se šalju između niti tako da možemo zaštititi kritični dio i izbjeći propuštene signale.
Semafor se može definirati kao varijabla koja se koristi za upravljanje istodobnim procesima sinkroniziranjem tih procesa. Semafori se također koriste za sinkronizaciju pristupa zajedničkom resursu i time izbjegavanje uvjeta utrke. Dopuštenje dano niti za pristup semaforu zajedničkom resursu naziva se i dozvolom.
Ovisno o funkcijama koje obavljaju, semafor se može podijeliti u dvije vrste:
# 1) Binarni semafor: Binarni semafor koristi se za sinkronizaciju istodobnih procesa i provedbu međusobnog izuzimanja. Binarni semafor poprima samo dvije vrijednosti, tj. 0 i 1.
# 2) Brojanje semafora: Semafor za brojanje ima vrijednost koja označava broj procesa koji mogu ući u kritični odjeljak. U bilo kojem trenutku, vrijednost označava maksimalan broj procesa koji ulaze u kritični odjeljak.
Pa kako funkcionira Semafor?
Rad Semafora može se sažeti u sljedećim koracima:
- Ako je broj semafora> 0, to znači da nit ima dozvolu za pristup kritičnom odjeljku, a zatim se brojanje smanjuje.
- U suprotnom, nit se blokira dok se ne stekne dozvola.
- Kada se nit završi s pristupom zajedničkom resursu, dozvola se oslobađa i povećava se broj semafora tako da druga nit može ponoviti gornje korake i steći dozvolu.
Gornji koraci rada semafora mogu se sažeti u donjem dijagramu toka.
U Javi ne trebamo implementirati svoj semafor, ali on pruža a Semafor klasa koja implementira funkcionalnost semafora. Klasa Semafor je dio java.util.concurrent paket.
Klasa Semaphore nudi sljedeće konstruktore pomoću kojih možemo stvoriti objekt semafora:
Semaphore (int num_value) Semaphore (int num_value, boolean how)
Ovdje,
num_value => početna vrijednost broja dozvola koja određuje broj niti koje mogu pristupiti zajedničkom resursu.
kako => postavlja redoslijed kojim će se nitima dodijeliti dozvole (kako = istinito). Ako je = false, tada se takav redoslijed ne slijedi.
Sada ćemo implementirati Java program koji će demonstrirati Semafor koji se koristi za upravljanje zajedničkim pristupom resursima i sprječavanje utrka.
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. } }
Izlaz
Ovaj je program proglasio klasu za zajednički resurs. Također deklarira klasu niti u kojoj imamo semaforsku varijablu koja je inicijalizirana u konstruktoru klase.
U metodi overridden run () klase Thread vrši se obrada instance niti u kojoj nit stječe dozvolu, pristupa dijeljenom resursu, a zatim izdaje dozvolu.
U glavnoj metodi proglasili smo dvije instance niti. Zatim se pokreću obje niti, a zatim čekaju pomoću metode pridruživanja. Konačno, prikazuje se brojanje, tj. 0 što znači da su obje niti završile sa zajedničkim resursom.
Fork i pridružite se Javi
Okvir fork / join prvi je put predstavljen u Javi 7. Ovaj okvir sastoji se od alata koji mogu ubrzati paralelnu obradu. Koristi sve dostupne procesorske jezgre u sustavu i dovršava zadatak. Okvir fork / join koristi pristup podijeli i osvoji.
Osnovna ideja iza okvira Fork / Join je da prvi okvir 'Forks', tj. Rekurzivno raščlanjuje zadatak na manje pojedinačne podzadaće dok zadaci ne postanu atomski kako bi se mogli izvršavati asinkrono.
Nakon toga zadaci se 'spajaju', tj. Sve se podzadaće rekurzivno spajaju u jedan zadatak ili povratnu vrijednost.
otvorite apk datoteku u sustavu Windows
Okvir fork / join ima skup niti poznatih kao “ForkJoinPool”. Ovaj bazen upravlja tipom „ForkJoinWorkerThread“ radničkih niti, pružajući tako učinkovitu paralelnu obradu.
ForkJoinPool upravlja radnim nitima i također nam pomaže dobiti informacije o izvedbi i stanju spremišta niti. ForkJoinPool je implementacija 'ExecutorService' o kojoj smo gore razgovarali.
Za razliku od radničkih niti, ForkJoinPool ne stvara zasebnu nit za svaki podzadatak. Svaka nit u ForkJoinPool održava svoj deque (dvostruki red čekanja) za spremanje zadataka.
Deque djeluje kao uravnoteženje radnog opterećenja niti i to uz pomoć 'algoritma za krađu rada' koji je opisan u nastavku.
Algoritam krađe posla
Algoritam krađe rada možemo definirati jednostavnim riječima kao 'Ako je nit slobodan, 'ukradite' posao od zauzetih niti'.
Radnička nit uvijek će zadatke dobivati iz svog razloga. Kada su svi zadaci u dequeu iscrpljeni, a deque prazan, radnička nit će preuzeti zadatak iz repa drugog dequea ili iz 'globalnog reda unosa'.
Na taj je način smanjena mogućnost nadmetanja niti za zadatke, a smanjen je i broj puta koji nit treba potražiti za poslom. To je zato što je nit već dobila najveći dio dostupnog posla i završila je.
Pa kako možemo koristiti ForkJoinPool u programu?
Opća definicija ForkJoinPool je kako slijedi:
public class ForkJoinPool extends AbstractExecutorService
Klasa ForkJoinPool dio je paketa 'java.util.concurrent'.
U Javi 8 kreiramo instancu ForkJoinPool koristeći njegovu statičku metodu “common-pool ()” koja pruža referencu na zajednički bazen ili zadani spremište niti.
ForkJoinPool commonPool = ForkJoinPool.commonPool ();
U Javi 7 kreiramo instancu ForkJoinPool i dodijeljujemo je polju klase uslužnih programa kao što je prikazano u nastavku.
public static ForkJoinPool forkJoinPool = new ForkJoinPool(2);
Gornja definicija pokazuje da spremište ima razinu paralelizma 2 takvu da će spremište koristiti 2 procesorske jezgre.
Za pristup gore navedenom spremištu možemo dati sljedeću izjavu.
ForkJoinPool forkJoinPool = PoolUtil.forkJoinPool;
Osnovni tip za zadatke ForkJoinPool je “ForkJoinTask”. Trebali bismo proširiti jednu od njegovih potklasa, tj. Za nevažeće zadatke, RecursiveAction i za zadatke koji vraćaju vrijednost, RecursiveTask. Obje proširene klase pružaju apstraktnu metodu compute () u kojoj definiramo logiku zadatka.
Dolje je dat primjer za demonstraciju ForkJoinPool-a.
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()); } }
Izlaz
U gornjem programu pronalazimo broj aktivnih niti u sustavu prije i nakon poziva metode „invoke ()“. Metoda invoke () koristi se za slanje zadataka u spremište. Također pronalazimo broj dostupnih procesorskih jezgri u sustavu.
Često postavljana pitanja
P # 1) Što je Java Util istovremeno?
Odgovor: Paket 'java.util.concurrent' skup je klasa i sučelja koje pruža Java za olakšavanje razvoja istodobnih (višenitnih) aplikacija. Korištenjem ovog paketa možemo izravno koristiti sučelje i klase, kao i API-je, a da ne moramo pisati naše klase.
P # 2) Koje su od sljedećih istodobne implementacije prisutne u java.util. istodobni paket?
Odgovor: Na visokoj razini, paket java.util.concurrent sadrži uslužne programe poput Izvršitelja, Sinkronizatora, Redova čekanja, Istovremenih zbirki.
P # 3) Što je buduća Java?
Odgovor: Budući objekt (java.util.concurrent.Future) koristi se za spremanje rezultata koje je nit vratila kada je implementirano sučelje za pozivanje.
P # 4) Što je u Java Java sigurno zaštićeno od niti?
Odgovor: Kôd ili klasa sigurni za nit u Javi je kôd ili klasa koji se bez problema mogu dijeliti u višenitnom ili istodobnom okruženju i daju očekivane rezultate.
P # 5) Što je sinkronizirana zbirka u Javi?
Odgovor: Sinkronizirana zbirka kolekcija je zaštićena nitima. Metoda sinkronizirana kolekcija () klase java.util.Collections vraća sinkroniziranu (nit-safe) kolekciju.
Zaključak
Ovim smo uputstvom dovršili temu višestrukog navoja i istodobnosti u Javi. O multithreading-u smo detaljno razgovarali u našim prethodnim vodičima. Ovdje smo razgovarali o paralelnosti i implementaciji vezanoj uz paralelnost i multithreading koji su dio java.util.concurrent paketa.
Razgovarali smo o još dvije metode sinkronizacije, semaforima i ReentrantLocku. Također smo razgovarali o ForkJoinPoolu koji se koristi za izvršavanje zadataka dijeleći ih na jednostavnije zadatke, a zatim na kraju pridružujući rezultat.
Paket java.util.concurrent također podržava Executor framework i izvršitelje koji nam pomažu u izvršavanju niti. Također smo razgovarali o implementaciji spremišta niti koja se sastoji od niti za višekratnu upotrebu koje se vraćaju u spremište kada je izvršenje završeno.
Razgovarali smo o drugom sučelju sličnom Runnableu koje nam također pomaže vratiti rezultat iz niti i objekta Future koji se koristi za pohranu dobivenog rezultata niti.
=> Ovdje pripazite na jednostavnu seriju Java treninga.
Preporučena literatura
- Thread.Sleep () - metoda spavanja niti () u Javi s primjerima
- Implementacija Jave: Izrada i izvršavanje Java JAR datoteke
- Osnove Java-a: Java sintaksa, Java Class i osnovni Java koncepti
- Java virtualni stroj: kako JVM pomaže u pokretanju Java aplikacije
- Pristupiti modifikatorima u Javi - Vodič s primjerima
- Java Synchronized: Što je sinkronizacija niti u Javi
- JAVA Tutorial za početnike: 100+ praktičnih Java Video tutorijala
- Java Integer i Java BigInteger klasa s primjerima