java synchronized what is thread synchronization java
Acest tutorial explică sincronizarea firului în Java împreună cu concepte conexe precum Java Lock, Race Condition, Mutex, Java Volatile și Deadlock în Java:
Într-un mediu multithreading în care sunt implicate mai multe fire de execuție, este obligatoriu să existe ciocniri atunci când mai mult de un thread încearcă să obțină aceeași resursă în același timp. Aceste ciocniri au ca rezultat „starea cursei” și astfel programul produce rezultate neașteptate.
De exemplu, un singur fișier este actualizat de două fire. Dacă un fir T1 este în curs de actualizare a acestui fișier, spuneți o variabilă. Acum, în timp ce această actualizare de T1 este încă în desfășurare, să presupunem că al doilea fir T2 actualizează, de asemenea, aceeași variabilă. În acest fel, variabila va da rezultate greșite.
=> Urmăriți aici seria completă de antrenament Java.
Atunci când sunt implicate mai multe fire, ar trebui să le gestionăm în așa fel încât o resursă să poată fi accesată de un singur fir la un moment dat. În exemplul de mai sus, fișierul care este accesat de ambele fire ar trebui să fie gestionat în așa fel încât T2 să nu poată accesa fișierul până când T1 nu este accesat.
Acest lucru se face în Java folosind „ Sincronizarea firului ”.
Ce veți învăța:
- Sincronizarea firului în Java
- Multi-threading fără sincronizare
- Multi-threading cu sincronizare
- Concluzie
Sincronizarea firului în Java
Deoarece Java este un limbaj multi_threaded, sincronizarea thread-urilor are multă importanță în Java, deoarece mai multe fire se execută în paralel într-o aplicație.
Folosim cuvinte cheie „Sincronizat” și 'volatil' pentru a realiza sincronizarea în Java
Avem nevoie de sincronizare atunci când obiectul sau resursa partajată este mutabil. Dacă resursa este imuabilă, atunci firele vor citi resursa numai simultan sau individual.
În acest caz, nu este nevoie să sincronizăm resursa. În acest caz, JVM asigură că Codul sincronizat Java este executat de câte un fir la rând .
De cele mai multe ori, accesul simultan la resursele partajate în Java poate introduce erori precum „inconsecvența memoriei” și „interferența firului”. Pentru a evita aceste erori, trebuie să optăm pentru sincronizarea resurselor partajate, astfel încât accesul la aceste resurse să se excludă reciproc.
Folosim un concept numit Monitoare pentru a implementa sincronizarea. Un monitor poate fi accesat de un singur fir la un moment dat. Atunci când un fir primește blocarea, atunci putem spune că firul a intrat pe monitor.
Atunci când un monitor este accesat de un anumit fir, acesta este blocat și toate celelalte fire care încearcă să intre în monitor sunt suspendate până când firul de acces se termină și eliberează blocarea.
În viitor, vom discuta în detaliu sincronizarea în Java în acest tutorial. Acum, să discutăm câteva concepte de bază legate de sincronizarea în Java.
Starea cursei în Java
Într-un mediu cu mai multe fire, atunci când mai multe fire încearcă să acceseze o resursă partajată pentru a scrie simultan, atunci mai multe fire se întrec între ele pentru a termina accesarea resursei. Acest lucru dă naștere la „starea de rasă”.
Un lucru de luat în considerare este că nu există nicio problemă dacă mai multe fire încearcă să acceseze o resursă partajată numai pentru citire. Problema apare atunci când mai multe fire de acces accesează aceeași resursă în același timp.
Condițiile de cursă apar din cauza lipsei sincronizării corecte a firelor din program. Când sincronizăm corect firele astfel încât, la un moment dat, un singur fir să acceseze resursa, iar starea cursei să nu mai existe.
Deci, cum detectăm starea cursei?
Cel mai bun mod de a detecta starea cursei este prin revizuirea codului. În calitate de programator, ar trebui să examinăm detaliat codul pentru a verifica condițiile de cursă potențiale care ar putea apărea.
Încuietori / monitoare în Java
Am menționat deja că folosim monitoare sau blocări pentru a implementa sincronizarea. Monitorul sau blocarea este o entitate internă și este asociat cu fiecare obiect. Deci, ori de câte ori un fir trebuie să acceseze obiectul, acesta trebuie să achiziționeze mai întâi blocarea sau monitorizarea obiectului său, să lucreze asupra obiectului și apoi să elibereze blocarea.
Blocările în Java vor arăta așa cum se arată mai jos:
public class Lock { private boolean isLocked = false; public synchronized void lock() throws InterruptedException { while(isLocked) { wait(); } isLocked = true; } public synchronized void unlock(){ isLocked = false; notify(); } }
Așa cum se arată mai sus, avem o metodă lock () care blochează instanța. Toate firele care apelează metoda lock () vor fi blocate până când seturile de metode deblocare () sunt blocate în steagul false și notifică toate firele de așteptare.
Câteva indicii de reținut despre încuietori:
- În Java, fiecare obiect are o blocare sau un monitor. Această blocare poate fi accesată printr-un fir.
- La un moment dat, un singur fir poate obține acest monitor sau blocare.
- Limbajul de programare Java oferă un cuvânt cheie Sincronizat 'care ne permite să sincronizăm firele prin realizarea unui bloc sau metodă ca Sincronizat.
- Resursele partajate pe care trebuie să le acceseze firele sunt păstrate sub acest bloc / metodă sincronizată.
Mutexes în Java
Am discutat deja că într-un mediu multithread, condițiile de cursă pot apărea atunci când mai multe fire încearcă să acceseze resursele partajate simultan și condițiile de cursă duc la rezultate neașteptate.
Partea programului care încearcă să acceseze resursa partajată se numește „Secțiunea critică” . Pentru a evita apariția condițiilor de cursă, este necesară sincronizarea accesului la secțiunea critică. Sincronizând această secțiune critică, ne asigurăm că un singur fir poate accesa secțiunea critică la un moment dat.
Cel mai simplu tip de sincronizator este „mutex”. Mutex se asigură că la orice instanță dată, un singur fir poate executa secțiunea critică.
Mutex este similar cu conceptul de monitoare sau încuietori pe care l-am discutat mai sus. Dacă un thread trebuie să acceseze o secțiune critică, atunci trebuie să dobândească mutex. Odată ce mutex este dobândit, firul va accesa codul secțiunii critice și, după ce a terminat, va elibera mutex.
Celelalte fire care așteaptă să acceseze secțiunea critică vor fi blocate între timp. De îndată ce firul care deține mutex îl eliberează, un alt fir va intra în secțiunea critică.
cele mai bune aplicații de telefonie spion pentru Android
Există mai multe moduri în care putem implementa un mutex în Java.
- Utilizarea cuvântului cheie sincronizat
- Folosind semafor
- Folosind ReentrantLock
În acest tutorial, vom discuta despre prima abordare, adică Sincronizarea. Celelalte două abordări - Semaphore și ReentrantLock vor fi discutate în următorul tutorial în care vom discuta despre pachetul simultan Java.
Cuvânt cheie sincronizat
Java oferă un cuvânt cheie „Sincronizat” care poate fi folosit într-un program pentru a marca o secțiune critică. Secțiunea critică poate fi un bloc de cod sau o metodă completă. Astfel, doar un singur fir poate accesa secțiunea critică marcată de cuvântul cheie sincronizat.
Putem scrie părțile concurente (părțile care se execută simultan) pentru o aplicație folosind cuvântul cheie sincronizat. De asemenea, scăpăm de condițiile cursei făcând un bloc de cod sau o metodă sincronizată.
Când marcăm un bloc sau o metodă sincronizată, protejăm resursele partajate din interiorul acestor entități de acces simultan și, prin urmare, de corupție.
Tipuri de sincronizare
Există 2 tipuri de sincronizare, după cum se explică mai jos:
# 1) Sincronizare proces
Sincronizarea proceselor implică mai multe procese sau fire care se execută simultan. În cele din urmă, acestea ajung într-o stare în care aceste procese sau fire se angajează la o anumită secvență de acțiuni.
# 2) Sincronizarea firului
În Sincronizarea firelor, mai multe fire încearcă să acceseze un spațiu partajat. Firele sunt sincronizate în așa fel încât spațiul partajat să fie accesat doar de un fir la rând.
Sincronizarea proceselor nu intră în sfera acestui tutorial. Prin urmare, vom discuta aici doar despre sincronizarea firului.
În Java, putem folosi cuvântul cheie sincronizat cu:
cel mai bun spion pentru telefonul mobil pentru Android
- Un bloc de cod
- O metodă
Tipurile de mai sus sunt tipurile de sincronizare a firelor care se exclud reciproc. Excluderea reciprocă împiedică firele care accesează datele partajate să se interfereze reciproc.
Celălalt tip de sincronizare a firelor este „comunicarea InterThread”, care se bazează pe cooperarea dintre fire. Comunicarea Interthread nu intră în sfera acestui tutorial.
Înainte de a continua cu sincronizarea blocurilor și metodelor, să implementăm un program Java pentru a demonstra comportamentul firelor atunci când nu există sincronizare.
Multi-threading fără sincronizare
Următorul program Java are mai multe fire care nu sunt sincronizate.
class PrintCount { //method to print the thread counter public void printcounter() { try { for(int i = 5; i > 0; i--) { System.out.println('Counter ==> ' + i ); } } catch (Exception e) { System.out.println('Thread interrupted.'); } } } //thread class class ThreadCounter extends Thread { private Thread t; private String threadName; PrintCount PD; //class constructor for initialization ThreadCounter( String name, PrintCount pd) { threadName = name; PD = pd; } //run method for thread public void run() { PD.printcounter(); System.out.println('Thread ' + threadName + ' exiting.'); } //start method for thread public void start () { System.out.println('Starting ' + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } } public class Main { public static void main(String args()) { PrintCount PD = new PrintCount(); //create two instances of thread class ThreadCounter T1 = new ThreadCounter( 'ThreadCounter_1 ', PD ); ThreadCounter T2 = new ThreadCounter( 'ThreadCounter_2 ', PD ); //start both the threads T1.start(); T2.start(); // wait for threads to end try { T1.join(); T2.join(); } catch ( Exception e) { System.out.println('Interrupted'); } } }
Ieșire
Din ieșire, putem vedea că, deoarece firele nu sunt sincronizate, ieșirea este inconsistentă. Ambele fire încep și apoi afișează contorul unul după altul. Ambele fire ies la sfârșit.
Din programul dat, primul fir ar trebui să fi ieșit după afișarea valorilor contorului, iar apoi al doilea fir ar fi trebuit să afișeze valorile contorului.
Acum, să mergem pentru sincronizare și să începem cu sincronizarea blocului de cod.
Bloc de cod sincronizat
Un bloc sincronizat este utilizat pentru a sincroniza un bloc de cod. Acest bloc constă de obicei din câteva linii. Un bloc sincronizat este utilizat atunci când nu dorim ca o metodă întreagă să fie sincronizată.
De exemplu, avem o metodă cu 75 de linii de cod. Din aceasta, numai 10 linii de cod trebuie executate de câte un fir la un moment dat. În acest caz, dacă realizăm întreaga metodă sincronizată, atunci va fi o povară pentru sistem. În astfel de situații, mergem pentru blocuri sincronizate.
Domeniul de aplicare al metodei sincronizate este întotdeauna mai mic decât cel al unei metode sincronizate. O metodă sincronizată blochează un obiect al unei resurse partajate care urmează să fie utilizat de mai multe fire.
Sintaxa generală a unui bloc sincronizat este așa cum se arată mai jos:
synchronized (lock_object){ //synchronized code statements }
Aici „lock_object” este o expresie de referință a obiectului pe care urmează să se obțină blocarea. Deci, ori de câte ori un fir de discuții dorește să acceseze instrucțiunile sincronizate din interiorul blocului pentru executare, atunci acesta trebuie să dobândească blocarea pe monitorul „lock_object”.
După cum sa discutat deja, cuvântul cheie sincronizat asigură că numai un fir poate obține o blocare la un moment dat și toate celelalte fire trebuie să aștepte până când firul care deține blocarea se termină și eliberează blocarea.
Notă
- O „NullPointerException” este aruncată dacă lock_object utilizat este Null.
- Dacă un fir doarme în timp ce încă ține încuietoarea, atunci încuietoarea nu este eliberată. Celelalte fire nu vor putea accesa obiectul partajat în acest timp de somn.
Acum vom prezenta exemplul de mai sus, care a fost deja implementat cu ușoare modificări. În programul anterior, nu am sincronizat codul. Acum vom folosi blocul sincronizat și vom compara ieșirea.
Multi-threading cu sincronizare
În programul Java de mai jos, folosim un bloc sincronizat. În metoda de rulare, sincronizăm codul liniilor care imprimă contorul pentru fiecare fir.
class PrintCount { //print thread counter public void printCounter() { try { for(int i = 5; i > 0; i--) { System.out.println('Counter ==> ' + i ); } } catch (Exception e) { System.out.println('Thread interrupted.'); } } } //thread class class ThreadCounter extends Thread { private Thread t; private String threadName; PrintCount PD; //class constructor for initialization ThreadCounter( String name, PrintCount pd) { threadName = name; PD = pd; } //run () method for thread with synchronized block public void run() { synchronized(PD) { PD.printCounter(); } System.out.println('Thread ' + threadName + ' exiting.'); } //start () method for thread public void start () { System.out.println('Starting ' + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } } public class Main { public static void main(String args()) { PrintCount PD = new PrintCount(); //create thread instances ThreadCounter T1 = new ThreadCounter( 'Thread_1 ', PD ); ThreadCounter T2 = new ThreadCounter( 'Thread_2 ', PD ); //start both the threads T1.start(); T2.start(); // wait for threads to end try { T1.join(); T2.join(); } catch ( Exception e) { System.out.println('Interrupted'); } } }
Ieșire
Acum, ieșirea acestui program utilizând blocul sincronizat este destul de consistentă. Așa cum era de așteptat, ambele fire încep să se execute. Primul fir a terminat de afișat valorile și ieșirile contorului. Apoi, al doilea fir afișează valorile contorului și iese.
Metoda sincronizată
Să discutăm metoda sincronizată în această secțiune. Mai devreme am văzut că putem declara un bloc mic format din mai puține linii de cod ca bloc sincronizat. Dacă dorim ca întreaga funcție să fie sincronizată, atunci putem declara o metodă ca fiind sincronizată.
Când o metodă este sincronizată, atunci un singur fir va putea efectua un apel de metodă la un moment dat.
Sintaxa generală pentru scrierea unei metode sincronizate este:
synchronized method_name (parameters){ //synchronized code }
La fel ca un bloc sincronizat, în cazul unei metode sincronizate, avem nevoie de un lock_object care va fi utilizat de firele care accesează metoda sincronizată.
Pentru metoda sincronizată, obiectul de blocare poate fi unul dintre următoarele:
- Dacă metoda sincronizată este statică, atunci obiectul de blocare este dat de obiectul „.class”.
- Pentru o metodă nestatică, obiectul de blocare este dat de obiectul curent, adică obiectul „acesta”.
O caracteristică particulară a cuvântului cheie sincronizat este că este reintroducător. Aceasta înseamnă că o metodă sincronizată poate apela o altă metodă sincronizată cu aceeași blocare. Deci, un fir care deține blocarea poate accesa o altă metodă sincronizată fără a fi nevoie să dobândească o altă blocare.
Metoda sincronizată este demonstrată folosind exemplul de mai jos.
class NumberClass { //synchronized method to print squares of numbers synchronized void printSquares(int n) throws InterruptedException { //iterate from 1 to given number and print the squares at each iteration for (int i = 1; i <= n; i++) { System.out.println(Thread.currentThread().getName() + ' :: '+ i*i); Thread.sleep(500); } } } public class Main { public static void main(String args()) { final NumberClass number = new NumberClass(); //create thread Runnable thread = new Runnable() { public void run() { try { number.printSquares(3); } catch (InterruptedException e) { e.printStackTrace(); } } }; //start thread instance new Thread(thread, 'Thread One').start(); new Thread(thread, 'Thread Two').start(); } }
Ieșire
În programul de mai sus, am folosit o metodă sincronizată pentru a imprima pătratele unui număr. Limita superioară a numărului este transmisă metodei ca argument. Apoi, începând de la 1, pătratele fiecărui număr sunt tipărite până la atingerea limitei superioare.
În funcția principală, se creează instanța firului. Fiecărei instanțe de thread i se transmite un număr pentru a imprima pătrate.
După cum sa menționat mai sus, atunci când o metodă care trebuie sincronizată este statică, atunci obiectul de blocare este implicat în clasă și nu obiectul. Aceasta înseamnă că vom bloca clasa și nu obiectul. Aceasta se numește sincronizare statică.
Un alt exemplu este dat mai jos.
class Table{ //synchronized static method to print squares of numbers synchronized static void printTable(int n){ for(int i=1;i<=10;i++){ System.out.print(n*i + ' '); try{ Thread.sleep(400); }catch(Exception e){} } System.out.println(); } } //thread class Thread_One class Thread_One extends Thread{ public void run(){ Table.printTable(2); } } //thread class Thread_Two class Thread_Two extends Thread{ public void run(){ Table.printTable(5); } } public class Main{ public static void main(String t()){ //create instances of Thread_One and Thread_Two Thread_One t1=new Thread_One (); Thread_Two t2=new Thread_Two (); //start each thread instance t1.start(); t2.start(); } }
Ieșire
În programul de mai sus, imprimăm tabele de înmulțire a numerelor. Fiecare număr a cărui tabel urmează să fie tipărit este o instanță de fir de clasă de fir diferită. Astfel, tipărim tabele de înmulțire de 2 și 5, deci avem două clase thread_one și thread_two pentru a imprima tabelele 2 și respectiv 5.
Pentru a rezuma, cuvântul cheie sincronizat Java îndeplinește următoarele funcții:
- Cuvântul cheie sincronizat în Java garantează accesul reciproc exclusiv la resursele partajate, oferind un mecanism de blocare. Blocarea previne și condițiile de cursă.
- Folosind cuvântul cheie sincronizat, prevenim erorile de programare simultane în cod.
- Când o metodă sau un bloc este declarat sincronizat, atunci un fir are nevoie de o blocare exclusivă pentru a introduce metoda sau blocul sincronizat. După efectuarea acțiunilor necesare, firul eliberează blocarea și va spăla operația de scriere. În acest fel, va elimina erorile de memorie legate de inconsecvență.
Volatil în Java
Un cuvânt cheie volatil în Java este utilizat pentru a face clasele sigure. De asemenea, folosim cuvântul cheie volatil pentru a modifica valoarea variabilei prin diferite fire. Un cuvânt cheie volatil poate fi utilizat pentru a declara o variabilă cu tipuri primitive, precum și obiecte.
În anumite cazuri, un cuvânt cheie volatil este utilizat ca alternativă pentru cuvântul cheie sincronizat, dar rețineți că nu este un substitut pentru cuvântul cheie sincronizat.
Când o variabilă este declarată volatilă, valoarea acesteia nu este niciodată memorată în cache, ci este citită întotdeauna din memoria principală. O variabilă volatilă garantează ordinea și vizibilitatea. Deși o variabilă poate fi declarată ca fiind volatilă, nu putem declara clase sau metode ca fiind volatile.
Luați în considerare următorul bloc de cod:
class ABC{ static volatile int myvar =10; }
În codul de mai sus, variabila myvar este statică și volatilă. O variabilă statică este partajată între toate obiectele clasei. Variabila volatilă se află întotdeauna în memoria principală și nu este niciodată memorată în cache.
Prin urmare, va exista o singură copie a myvar în memoria principală și toate acțiunile de citire / scriere se vor face pe această variabilă din memoria principală. Dacă myvar nu a fost declarat volatil, atunci fiecare obiect thread ar avea o copie diferită care ar duce la inconsecvențe.
Unele dintre diferențele dintre cuvintele cheie volatile și cele sincronizate sunt enumerate mai jos.
Cuvânt cheie volatil | Cuvânt cheie sincronizat |
---|---|
Cuvântul cheie volatil este utilizat numai cu variabile. | Cuvântul cheie sincronizat este utilizat cu blocuri de cod și metode. |
Un cuvânt cheie volatil nu poate bloca firul pentru așteptare. | Cuvântul cheie sincronizat poate bloca firul de așteptare. |
Performanța firului este îmbunătățită cu Volatile. | Performanța firului se degradează oarecum cu sincronizarea. |
Variabilele volatile se află în memoria principală. | Construcțiile sincronizate nu se află în memoria principală. |
Volatile sincronizează o variabilă între memoria thread și memoria principală la un moment dat. | Cuvântul cheie sincronizat sincronizează toate variabilele simultan. |
Impas în Java
Am văzut că putem sincroniza mai multe fire utilizând cuvinte cheie sincronizate și putem face programele sigure. Prin sincronizarea firelor, ne asigurăm că firele multiple se execută simultan într-un mediu cu mai multe fire.
Cu toate acestea, uneori apare o situație în care firele nu mai pot funcționa simultan. În schimb, așteaptă la nesfârșit. Acest lucru se întâmplă atunci când un fir așteaptă o resursă și resursa respectivă este blocată de al doilea fir.
Al doilea fir, pe de altă parte, așteaptă resursa blocată de primul fir. O astfel de situație dă naștere unui „impas” în Java.
Blocajul în Java este descris folosind imaginea de mai jos.
După cum putem vedea din diagrama de mai sus, firul A a blocat resursa r1 și așteaptă resursa r2. Firul B, pe de altă parte, a blocat resursa r2 și așteaptă pe r1.
Astfel, niciunul dintre fire nu își poate termina execuția decât dacă obține resursele în așteptare. Această situație a dus la blocarea în care ambele fire așteaptă la nesfârșit resursele.
Dat mai jos este un exemplu de blocaje în Java.
public class Main { public static void main(String() args) { //define shared resources final String shared_res1 = 'Java tutorials'; final String shared_res2 = 'Multithreading'; // thread_one => locks shared_res1 then shared_res2 Thread thread_one = new Thread() { public void run() { synchronized (shared_res1) { System.out.println('Thread one: locked shared resource 1'); try { Thread.sleep(100);} catch (Exception e) {} synchronized (shared_res2) { System.out.println('Thread one: locked shared resource 2'); } } } }; // thread_two=> locks shared_res2 then shared_res1 Thread thread_two = new Thread() { public void run() { synchronized (shared_res2) { System.out.println('Thread two: locked shared resource 2'); try { Thread.sleep(100);} catch (Exception e) {} synchronized (shared_res1) { System.out.println('Thread two: locked shared resource 1'); } } } }; //start both the threads thread_one.start(); thread_two.start(); } }
Ieșire
În programul de mai sus, avem două resurse comune și două fire. Ambele fire încearcă să acceseze resursele partajate unul câte unul. Ieșirea arată ambele fire care blochează câte o resursă în așteptarea celorlalte. Prin aceasta se creează o situație de impas.
Deși nu putem opri situațiile de blocaj să apară complet, cu siguranță le putem evita luând niște pași.
Mai jos sunt enumerate mijloacele prin care putem evita blocajele în Java.
# 1) Prin evitarea încuietorilor imbricate
A avea încuietori imbricate este cel mai important motiv pentru a avea blocaje. Blocările imbricate sunt blocările care sunt date mai multor fire. Astfel, ar trebui să evităm blocarea mai multor fire.
# 2) Utilizați unirea thread
Ar trebui să folosim Thread.join cu timp maxim, astfel încât firele să poată utiliza timpul maxim pentru execuție. Acest lucru va preveni blocajul care apare mai ales pe măsură ce un fir îi așteaptă în mod continuu pe alții.
# 3) Evitați blocarea inutilă
Ar trebui să blocăm numai codul necesar. Dacă aveți blocări inutile pentru cod, puteți duce la blocaje în program. Deoarece blocajele pot rupe codul și pot împiedica fluxul programului, ar trebui să fim înclinați să evităm blocajele în programele noastre.
întrebări frecvente
Q # 1) Ce este sincronizarea și de ce este importantă?
Răspuns: Sincronizarea este procesul de control al accesului unei resurse partajate la mai multe fire. Fără sincronizare, mai multe fire pot actualiza sau modifica resursa partajată în același timp, rezultând inconsecvențe.
Astfel, ar trebui să ne asigurăm că într-un mediu multi-thread, thread-urile sunt sincronizate astfel încât modul în care accesează resursele partajate să se excludă reciproc și să fie consecvent.
Q # 2) Ce este sincronizarea și nesincronizarea în Java?
Răspuns: Sincronizarea înseamnă că o construcție este sigură pentru fire. Aceasta înseamnă că mai multe fire nu pot accesa construcția (bloc de cod, metodă etc.) simultan.
Construcțiile nesincronizate nu sunt sigure pentru fire. Mai multe fire pot accesa oricând metodele sau blocurile nesincronizate. O clasă populară nesincronizată în Java este StringBuilder.
Î. 3) De ce este necesară sincronizarea?
Răspuns: Când procesele trebuie să se execute simultan, avem nevoie de sincronizare. Acest lucru se datorează faptului că avem nevoie de resurse care pot fi partajate între multe procese.
Pentru a evita confruntările între procese sau fire pentru accesarea resurselor partajate, trebuie să sincronizăm aceste resurse, astfel încât toate firele să aibă acces la resurse și aplicația să funcționeze, de asemenea, fără probleme.
Q # 4) Cum obțineți o listă de matrice sincronizată?
Răspuns: Putem folosi metoda Collections.synchronized list cu ArrayList ca argument pentru a converti ArrayList într-o listă sincronizată.
Q # 5) HashMap este sincronizat?
coadă dublă terminată c ++
Răspuns: Nu, HashMap nu este sincronizat, dar HashTable este sincronizat.
Concluzie
În acest tutorial, am discutat în detaliu Sincronizarea firelor. Odată cu aceasta, am aflat și despre cuvintele cheie volatile și blocaje în Java. Sincronizarea constă în sincronizarea procesului și a firului.
Într-un mediu multithreading, suntem mai preocupați de sincronizarea firelor. Am văzut aici abordarea sincronizată a cuvintelor cheie a sincronizării firelor.
Blocajul este o situație în care mai multe fire de așteptare la nesfârșit pentru resurse. Am văzut exemplul blocajelor în Java împreună cu metodele de evitare a blocajelor în Java.
=> Vizitați aici pentru a afla Java de la zero.
Lectură recomandată
- Thread.Sleep () - Metoda Thread Sleep () în Java cu exemple
- Fire Java cu metode și ciclu de viață
- Noțiuni de bază Java: Sintaxă Java, Java Class și concepte de bază Java
- Multithreading în Java - Tutorial cu exemple
- Multithreading în C ++ cu exemple
- Tutorial JAVA pentru începători: peste 100 de cursuri video Java practice
- Componente Java: platformă Java, JDK, JRE și mașină virtuală Java
- Tutorial Java String | Metode Java String cu exemple