multithreading java tutorial with examples
Acest tutorial explică totul despre Multithreading în Java, Implementarea simultană, ciclul de viață al unui thread, Exemplu de clasă Thread, Thread utilizând interfața Runnable:
Concurența în lumea computerelor este capacitatea unui sistem (fie că este vorba de aplicație, computer sau limbaj de programare) de a executa mai multe instanțe ale unui program sau aplicație în paralel.
Executând simultan instanțe sau programe, asigurăm un randament ridicat și performanțe mai mari, deoarece putem utiliza resursele neexploatate, cum ar fi hardware-ul sistemului de operare etc. De exemplu, dacă un sistem are mai multe procesoare, atunci aplicația poate utiliza aceste procesoare în mod eficient și poate crește randamentul.
=> Vizitați aici pentru seria exclusivă de instruiri Java.
Ce veți învăța:
- Ce este Multithreading în Java
- Ce este un fir în Java
- Concluzie
Ce este Multithreading în Java
În Java, firele pot fi privite ca coloana vertebrală a concurenței. Un thread este o unitate executabilă, ușoară, care accesează resursele partajate, precum și propria stivă de apeluri.
O aplicație Java este un proces și în cadrul acestei aplicații putem avea mai multe fire pentru a obține concurență.
Știm că o aplicație care rulează pe sistem poate avea mai multe instanțe și acestea sunt de obicei numite aplicații multi-doc. Aceste instanțe de aplicație sunt numite procese. Fiecăruia dintre aceste procese i se atribuie o unitate de execuție cunoscută sub numele de thread.
În funcție de sistemul de operare și cerințele aplicației, procesului i se poate atribui fie un singur fir, fie mai multe fire. Când procesului de aplicare i se atribuie mai multe fire, atunci trebuie să executăm simultan aceste fire multiple.
' Această tehnică de a executa sau rula mai multe fire simultan sau simultan este cunoscută sub numele de multithreading . '
Multithreading înseamnă pur și simplu că-avem mai multe fire executate în aceeași aplicație.
Limbajul de programare Java are suport încorporat pentru multithreading.
Multithreading este descris în diagrama de mai sus. După cum se arată, există mai multe fire care rulează simultan în interiorul unei aplicații.
De exemplu, o aplicație desktop care oferă funcționalități precum editarea, imprimarea etc. este o aplicație cu mai multe fire. În această aplicație, deoarece tipărirea este un proces de fundal, putem efectua editarea și tipărirea documentelor simultan prin atribuirea acestor funcții la două fire diferite.
Subiectele din aplicațiile cu mai multe fire rulează paralel între ele într-o manieră concurentă. Astfel multithreading este, de asemenea, o parte a concurenței în Java. Rețineți că, deși există mai multe fire, acestea împart zona de memorie economisind astfel în memorie. De asemenea, firele pot schimba cu ușurință contextele în cel mai scurt timp.
Multithreading este util în principal, deoarece oferă executarea simultană a două sau mai multe părți ale unei aplicații. Acest lucru permite aplicației să utilizeze timpul procesorului la maxim și timpul de inactivitate este redus la minimum.
Următorii sunt câțiva dintre termenii pe care ar trebui să-i cunoaștem în legătură cu mediul multithreading, deoarece sunt utilizați frecvent.
Multifunctional: În multitasking, mai multe sarcini sunt executate în același timp.
Multithreading: Multithreading, așa cum am menționat deja, este un proces de executare simultană a mai multor fire.
tutorial cu dublă legătură cu lista c ++
Multiprocesare: În multiprocesare, mai multe procese sunt executate simultan. Similar cu multitasking-ul, dar aici sunt implicate mai multe CPU.
Procesare paralelă: Procesarea în paralel este o tehnică în care mai multe procesoare funcționează simultan într-un sistem informatic.
După ce am discutat despre multithreading, se pune întrebarea de ce avem nevoie de multithreading?
Avantajele Multithreading-ului
Multithreading are diferite avantaje care ajută la programarea eficientă.
Punctele de mai jos o vor clarifica.
# 1) Utilizarea eficientă a sistemelor cu un singur procesor
Când există un singur procesor în sistem, cu un singur fir, atunci timpul procesorului este pierdut. Când firul este ocupat folosind alte resurse precum IO, CPU-ul este inactiv. Putem îmbunătăți acest lucru și putem utiliza mai bine procesorul având aplicații cu mai multe fire.
Utilizând multithreading, dacă un fir este realizat cu CPU, atunci celălalt fir îl poate utiliza. Cu mai multe fire, timpul de inactivitate al procesorului va fi redus foarte mult.
# 2) Utilizarea eficientă a mai multor sisteme CPU
La fel ca procesoarele individuale, chiar și cu sistemele care au mai multe procesoare, aplicațiile multithread sunt capabile să utilizeze mai multe procesoare în mod eficient.
# 3) Experiență îmbunătățită a utilizatorului în ceea ce privește sensibilitatea și corectitudinea
Răspunsul sistemului se îmbunătățește cu aplicațiile cu mai multe fire. Nu experimentăm „Suspendare GUI” atunci când avem mai multe fire care realizează diverse sarcini în aplicație și utilizatorii nu trebuie să aștepte mult timp pentru a obține un răspuns pentru solicitările lor.
În mod similar, utilizatorii sunt în mod corespunzător servicii în sisteme multithread.
Cum să implementați concurența în Java
Prima clasă cu care putem implementa concurența în Java este java.lang.Thread clasă. Această clasă Thread constituie baza concurenței în Java.
De asemenea avem java.lang.Runnable interfață care poate fi implementată de o clasă Java pentru a abstra comportamentul firului. Pentru dezvoltarea avansată a aplicațiilor, putem folosi java.util.concurrent pachet disponibil de la Java 1.5.
Înainte vom discuta în detaliu concurența în Java. Să discutăm și să înțelegem conceptul de fire în Java în acest tutorial. În tutorialele noastre ulterioare despre multithreading, vom explora diverse concepte de multithreading și concurență.
Ce este un fir în Java
Un singur fir poate fi definit ca cea mai mică și ușoară unitate de procesare. În Java, firele sunt utilizate în programe care utilizează clasa „Thread”.
Firele Java sunt de două tipuri:
# 1) Fir de utilizator: firul de utilizator este creat atunci când aplicația pornește pentru prima dată. Apoi, putem crea cât mai multe fire de utilizator și demon.
# 2) Fir de demon: firele de demoni sunt utilizate în principal în fundal și sunt utilizate pentru sarcini precum curățarea aplicației etc.
Firele reduc costurile de întreținere ale aplicației. De asemenea, reduce cheltuielile generale ale aplicației.
Un exemplu de fir unic este prezentat mai jos:
public class Main{ public static void main (String [] args){ System.out.println('This is a thread'); } }
Programul de mai sus va afișa „Acesta este un fir” ca atunci când aplicația pornește, se creează un fir de utilizator. În programul de mai sus, funcția principală este punctul de plecare al aplicației și creează un fir de utilizator.
Ciclul de viață al unui fir
Următoarea diagramă ilustrează ciclul de viață al unui fir în Java.
După cum se arată în diagrama de mai sus, un fir în Java are următoarele stări:
# 1) Nou: Inițial, firul tocmai creat din clasa thread are o stare „nouă”. Este încă de început. Acest fir este, de asemenea, numit „Fir născut” .
# 2) Runable: În această stare, instanța unui thread este invocată folosind metoda 'start' .
# 3) Alergare: Se invocă metoda de pornire a instanței firului și firul începe executarea. Aceasta este starea de rulare. În principal, programatorul planifică și gestionează firele.
# 4) Blocat: Există mai multe fire într-o aplicație. Aceste fire trebuie să aștepte altul, deoarece execuția lor trebuie sincronizată.
# 5) Terminat: Odată ce procesul de execuție a firului este încheiat, firul este încheiat sau executarea acestuia este oprită.
Deci, mai întâi se creează un fir, apoi este programat și mai târziu programatorul execută firul. În timp ce firul de rulare poate fi blocat sau suspendat pentru alte activități. Apoi este reluat și în timp ce procesarea se finalizează, firul este executat.
Prioritățile firului
O prioritate a firului decide cum trebuie tratat un fir în raport cu celelalte fire dintr-o aplicație. O prioritate a firului este un număr întreg.
Mai jos sunt prezentate câteva puncte de reținut despre prioritățile firului:
- Prioritățile firului sunt numere întregi.
- Folosind prioritatea firului, putem decide când ar trebui să trecem de la un fir în stare de rulare la altul. Acesta este procesul de comutare a contextului în care schimbăm contextele firelor.
- Oricând un fir își poate elibera voluntar controlul asupra procesorului. Apoi firul cu cea mai mare prioritate poate prelua.
- În mod similar, un fir cu prioritate mai mare poate preveni orice alt fir cu prioritate mai mică.
- Clasa Thread oferă o metodă setPriority () care este utilizată pentru a seta prioritatea firului.
- De asemenea, putem folosi constante MIN_PRIORITY, MAX_PRIORITY sau NORM_PRIORITY în locul numerelor întregi.
Creați un subiect
Putem crea un thread utilizând oricare dintre următoarele moduri:
- Extinderea clasei Java „Thread”.
- Implementarea „Runnable”.
Extinderea clasei „Thread” Java
Clasa „Thread” conține constructorii și metodele care ne permit să creăm și să efectuăm operațiuni pe un obiect thread. Intern, clasa Thread implementează interfața Runnable și extinde, de asemenea, clasa Object.
Tabelul următor oferă un rezumat al diferiților constructori și metode ale unei clase Thread ().
Constructor/ | Prototip | Descriere |
---|---|---|
dormi | somn public gol (milisecunde lungi) | Execuția firului curent este oprită pentru milisecunde specificate. |
Thread () constructor | Fir() | Constructor implicit pentru a crea un obiect Thread. |
Fir (nume șir) | Constructor pentru a crea un obiect Thread cu numele specificat. | |
Fir (Runnable r) | Creați o instanță Thread cu obiectul de interfață Runnable specificat. | |
Fir (r Runable, nume șir) | Creați o instanță Thread cu obiectul de interfață Runnable specificat și numele dat | |
alerga | public void run () | Metoda Run execută acțiunea pentru un fir. Invocă firul. |
start | public vid start () | Folosit pentru a începe executarea firului. La nivel intern, apelurile JVM rulează () metoda pe acest fir. |
a te alatura | public void join () | Așteptați să moară firul |
aderare nulă publică (milisecunde lungi) | Așteptați milisecundele specificate pentru ca firul să moară. | |
getPriority | public int getPriority () | Returnează prioritatea firului |
stabilește prioritatea | public int setPriority (prioritate int) | Schimbați prioritatea firului la prioritatea specificată |
getName | public String getName () | returnează numele firului. |
Pune un nume | public void setName (numele șirului) | Setați numele firului la șirul specificat |
currentThread | fir public currentThread () | Returnează referința firului care este activ în prezent |
getId | public int getId () | Returnează ID-ul firului |
getState () | Thread.State public getState () | Returnează starea curentă a firului |
este in viata | public boolean isAlive () | Verificați dacă firul este viu și reveniți adevărat dacă da. |
Randament | public nul randament () | Întrerupe temporar firul curent și permite altor fire să se execute. |
isDaemon | public boolean isDaemon () | Verificați dacă firul este un fir de demon; returnează adevărat dacă da. |
setDaemon | public void setDaemon (boolean b) | Setați firul ca un fir de demon dacă b = adevărat; altfel setat ca fir de utilizator. |
întrerupe | public void interrupt () | Întrerupeți firul curent. |
este întreruptă | public boolean isInterrupted () | Verificați dacă firul este întrerupt. |
întrerupt | public boolean static întrerupt () | Verificați dacă firul curent a fost întrerupt. |
dumpStack | Static vid dumpStack () | Tipărește o urmă de stivă a firului curent în fluxul de erori standard. |
suspenda | public void suspend () | Suspendă toate firele. (** metoda este depreciată în cele mai recente versiuni Java) |
relua | CV public nul () | Reluați firul suspendat. (** metoda este depreciată în cele mai recente versiuni Java) |
Stop | public nul stop () | Oprește firul. (** metoda este depreciată în cele mai recente versiuni Java) |
Vom detalia aceste metode de thread în următorul nostru tutorial despre multithreading.
Pornirea unui fir
Metoda start () care este utilizată pentru a porni firul execută pașii următori:
- Pornește o nouă instanță de fir cu un nou CallStack.
- Starea firului se schimbă din nou în rulabil.
- Când este rândul firului, acesta execută metoda run ().
Implementarea interfeței „Runnable”
O instanță de fir poate fi de asemenea creată utilizând interfața Runnable. Pentru a crea o instanță thread, clasa ale cărei obiecte ar trebui executate de un thread ar trebui să implementeze interfața Runnable.
Interfața Runnable are o singură metodă:
care dintre următoarele este adevărat pentru un test de sistem?
public void run () => this method is used to execute the thread.
Exemplu de clasă de fire
Acum să demonstrăm firul în Java folosind clasa de fire.
//class inherited from 'Thread' class ThreadClassDemo extends Thread { private int number; //class constructor public ThreadClassDemo(int number) { this.number = number; } //run method => execution code for thread public void run() { int counter = 0; int numInt = 0; //prints the number till specified number is reached, starting from 10 do { numInt = (int) (counter + 10); System.out.println(this.getName() + ' prints ' + numInt); counter++; } while(numInt != number); System.out.println('** Correct! ' + this.getName() + 'printed ' + counter + ' times.**'); } } public class Main { public static void main(String [] args) { System.out.println('Starting thread_1...'); //create a thread class instance Thread thread_1 = new ThreadClassDemo(15); //start the thread thread_1 thread_1.start(); try { //wait for thread_1 to die thread_1.join(); } catch (InterruptedException e) { System.out.println('Thread interrupted.'); } System.out.println('Starting thread_2...'); Thread thread_2 = new ThreadClassDemo(20); //start thread_2 thread_2.start(); System.out.println('main() is ending...'); } }
Ieșire
Subiect Java utilizând interfața Runable
Următorul exemplu demonstrează utilizarea interfeței Runnable pentru a crea o instanță thread.
//class implements Runnable interface class RunnableDemo implements Runnable { private String message; //class constructor public RunnableDemo(String message) { this.message = message; } //run method public void run() { while(true) { System.out.println(message); } } } public class Main { public static void main(String [] args) { //create first thread instance hello Runnable hello = new RunnableDemo('Hello, Greetings!!!'); Thread thread1 = new Thread(hello); thread1.setDaemon(true); //set this thread as daemon thread1.setName('hello'); System.out.println('Starting First thread...'); //start the thread thread1.start(); //create second thread instance bye Runnable bye = new RunnableDemo('Bye for now!!'); Thread thread2 = new Thread(bye); thread2.setPriority(Thread.MIN_PRIORITY); //set priority to min thread2.setDaemon(true); //set as daemon thread System.out.println('Starting goodbye thread...'); //start the thread thread2.start(); System.out.println('main() is ending...'); } }
Ieșire
Cum să opriți un fir în Java
Am văzut exemplele de mai sus. Din aceste exemple, știm că atunci când metoda de executare termină execuția, firul se oprește sau se oprește și din cauza unor excepții.
Versiunile anterioare de Java aveau o metodă stop () în clasa Thread care putea fi utilizată pentru a opri direct thread-ul. Dar acum a fost depreciat din motive de siguranță. Astfel, trebuie să folosim celelalte metode pentru a opri firul care se execută.
Există două metode pe care le putem folosi pentru a opri firul.
- Folosind o variabilă booleană volatilă
- Utilizarea întreruperilor.
În această secțiune, vom discuta despre aceste două metode de oprire a unui fir.
Folosind o variabilă booleană volatilă
În această metodă, menținem o variabilă booleană, să spunem flag, pentru a opri firul. Firul rulează atâta timp cât variabila booleană este setată la adevărat. În momentul în care devine fals, firul este oprit.
Specialitatea acestei metode este că declarăm variabila booleană ca „ volatil ”Astfel încât să fie citit întotdeauna din memoria principală și programul să nu-l poată ascunde în memoria cache a procesorului. În acest fel, nu va exista nicio diferență în valorile setate și citite.
Implementarea opririi unui thread utilizând o variabilă booleană volatilă este prezentată mai jos.
class StopThread extends Thread { private volatile boolean stop_flag = true; //initially set to true public void stopRunning() { stop_flag = false; //set stop_flag to false } @Override public void run() { while (stop_flag) { //keep checking value of stop_flag System.out.println('Thread is running...'); } System.out.println('Thread stopped!!!'); } } public class Main { public static void main(String[] args) { //create a thread instance StopThread stop_thread = new StopThread(); //start the thread stop_thread.start(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //call stopRunning() method to stop the thread stop_thread.stopRunning(); } }
Ieșire
Notă: Aici am arătat doar o parte din ieșire. Firul poate rula câteva minute înainte de oprire. Astfel încât să putem obține rezultate diferite pe diferite sisteme.
Utilizarea întreruperilor
Aici firul este oprit folosind metoda interrupt () așa cum am discutat deja mai sus în metodele clasei de fire. Metoda interrupt () stabilește starea firului ca întrerupt. Această stare este transmisă buclei while a metodei run (). Putem obține starea întreruptă folosind metoda interrupted ().
Următorul program demonstrează utilizarea metodei interrupt () pentru a opri firul.
class StopThread extends Thread { @Override public void run() { while (!Thread.interrupted()) { //check for interrupted status System.out.println('Thread is running...'); } System.out.println('Thread stopped!!!'); } } public class Main { public static void main(String[] args) { //create a thread instance StopThread stop_thread = new StopThread(); //start the thread stop_thread.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //interrupt the thread stop_thread.interrupt(); } }
Ieșire
întrebări frecvente
Q # 1) De ce folosim Multithreading în Java?
Răspuns: Multithreading permite executarea simultană sau simultană a două sau mai multe thread-uri într-o aplicație. Execuția simultană maximizează debitul și, de asemenea, utilizează CPU la maximum.
Q # 2) Ce este Multithreading? Care sunt tipurile sale?
Răspuns: Multithreading înseamnă executarea mai multor fire. Această execuție poate fi concurentă sau paralelă. Astfel, multithreading are două tipuri, adică simultane sau paralele.
Q # 3) Ce este Multithreading vs. Multiprocessing?
Răspuns: În multithreading, există mai multe fire de execuție pentru aceleași procese sau diferite, iar aceste fire de execuție se execută simultan pentru a spori viteza de calcul a unui sistem. În multiprocesare, un sistem are mai mult de două procesoare și se execută simultan mai multe procese.
Q # 4) Care sunt avantajele Multithreading în Java?
Răspuns: Folosind multithreading putem executa simultan diferite părți ale unei aplicații folosind fire. Multithreading crește capacitatea de transfer a sistemului. Multithreading maximizează, de asemenea, utilizarea procesorului, deoarece diferite fire utilizează în mod continuu CPU.
Î # 5) Multithreading este bun pentru jocuri?
Răspuns: Da, mai ales pentru jocurile moderne.
Concluzie
Aici este vorba despre introducerea multithreading-ului. Am discutat simultanitatea și multi-threading-ul în Java în acest tutorial. Am discutat despre crearea unui thread cu clasa Thread, precum și cu interfața Runnable și am oferit exemple adecvate.
De asemenea, am învățat în detaliu conceptele unui singur fir și crearea acestuia. Conceptele de thread, inclusiv ciclul de viață al unui thread, oprirea unui thread, tipurile de thread etc., au fost discutate în acest tutorial.
Am discutat, de asemenea, multithreading pe lungime și concurență în Java. La sfârșitul acestui tutorial, cititorul ar trebui să poată înțelege cu ușurință conceptele de concurență și multithreading și, de asemenea, firele în Java.
=> Urmăriți aici seria de antrenament Java simplă.
Lectură recomandată
- Multithreading în C ++ cu exemple
- Fire Java cu metode și ciclu de viață
- Thread.Sleep () - Metoda Thread Sleep () în Java cu exemple
- Tutorial JAVA pentru începători: peste 100 de cursuri video Java practice
- Tutorial de reflecție Java cu exemple
- Șirul Java conține () Tutorial metodă cu exemple
- Matrice Jagged în Java - Tutorial cu exemple
- Tutorial de clasă Java Scanner cu exemple