java synchronized what is thread synchronization java
Tento tutoriál vysvetľuje synchronizáciu vlákien v Jave spolu s príbuznými konceptmi ako Java Lock, Race Condition, Mutex, Java Volatile & Deadlock v Java:
V prostredí viacerých vlákien, kde je zapojených viac vlákien, dôjde určite k stretom, keď sa viac vlákien pokúsi získať rovnaký zdroj súčasne. Výsledkom týchto stretov je „závodný stav“, a preto program prináša neočakávané výsledky.
Napríklad, jeden súbor sa aktualizuje o dve vlákna. Ak je jedno vlákno T1 v procese aktualizácie tohto súboru, povedzte nejakú premennú. Zatiaľ čo táto aktualizácia od T1 stále prebieha, povedzme, že druhá vlákno T2 tiež aktualizuje rovnakú premennú. Takto bude mať premenná nesprávne výsledky.
=> Tu si môžete pozrieť kompletnú sériu školení Java.
Ak je zapojených viac vlákien, mali by sme tieto vlákna spravovať tak, aby k prostriedku bolo možné pristupovať naraz iba po jednom vlákne. Vo vyššie uvedenom príklade by mal byť súbor, ku ktorému majú prístup obidve vlákna, spravovaný takým spôsobom, aby T2 k nemu nemohla získať prístup, kým k nemu T1 nepristúpi.
To sa deje v Jave pomocou „ Synchronizácia vlákna “.
Čo sa dozviete:
- Synchronizácia vlákien v Jave
- Viacvláknové spracovanie bez synchronizácie
- Multi-threading so synchronizáciou
- Záver
Synchronizácia vlákien v Jave
Pretože Java je viacvláknový jazyk, synchronizácia vlákien má v Jave veľký význam, pretože viaceré vlákna sa v aplikácii vykonávajú paralelne.
Používame kľúčové slová „Synchronizované“ a „Nestály“ dosiahnuť synchronizáciu v Jave
Synchronizáciu potrebujeme, keď je zdieľaný objekt alebo zdroj premenlivý. Ak je prostriedok nemenný, vlákna ho budú čítať iba súbežne alebo jednotlivo.
V takom prípade nemusíme zdroj synchronizovať. V takom prípade to spoločnosť JVM zabezpečí Synchronizovaný kód Java sa vykonáva po jednom vlákne .
Súčasný prístup k zdieľaným prostriedkom v Jave môže väčšinou spôsobovať chyby ako „Nekonzistencia pamäte“ a „interferencia vlákien“. Aby sme sa vyhli týmto chybám, musíme ísť na synchronizáciu zdieľaných zdrojov, aby sa prístup k týmto zdrojom vzájomne vylučoval.
Používame koncept tzv Monitory na implementáciu synchronizácie. K monitoru je prístup naraz iba z jedného vlákna. Keď vlákno dostane zámok, môžeme povedať, že vlákno vstúpilo na monitor.
Pri prístupe na monitor pomocou konkrétneho vlákna je monitor uzamknutý a všetky ďalšie vlákna, ktoré sa pokúšajú vstúpiť na monitor, sú pozastavené, kým prístupové vlákno nedokončí a neuvoľní zámok.
Ďalej sa budeme v tomto tutoriále venovať synchronizácii v Jave. Teraz si povieme niekoľko základných pojmov týkajúcich sa synchronizácie v Jave.
Stav závodu v Jave
Keď sa v prostredí s viacerými vláknami pokúsi viac ako jedno vlákno získať prístup k zdieľanému prostriedku na súčasné písanie, potom sa viaceré vlákna navzájom pretekajú, aby dokončili prístup k prostriedku. To vedie k „rasovým podmienkam“.
Je potrebné vziať do úvahy, že nie je problém, ak sa viacnásobné vlákna pokúšajú získať prístup k zdieľanému prostriedku iba na čítanie. Problém nastáva, keď viac vlákien pristupuje k rovnakému prostriedku súčasne.
Podmienky preteku sa vyskytujú z dôvodu nedostatočnej synchronizácie vlákien v programe. Keď správne synchronizujeme vlákna tak, že k zdroju bude mať prístup vždy len jedno vlákno a rasová podmienka prestane existovať.
Ako teda zistíme stav rasy?
Najlepším spôsobom, ako zistiť stav rasy, je kontrola kódu. Ako programátor by sme mali dôkladne skontrolovať kód, aby sme skontrolovali potenciálne rasové podmienky, ktoré by sa mohli vyskytnúť.
Zámky / monitory v Jave
Už sme spomenuli, že na implementáciu synchronizácie používame monitory alebo zámky. Monitor alebo zámok je interná entita a je spojený s každým objektom. Takže vždy, keď vlákno potrebuje prístup k objektu, musí najskôr získať zámok alebo monitorovať svoj objekt, pracovať s objektom a potom zámok uvoľniť.
Zámky v Jave budú vyzerať nasledovne:
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(); } }
Ako je uvedené vyššie, máme metódu lock (), ktorá inštanciu uzamkne. Všetky vlákna volajúce metódu lock () budú blokované, kým nie sú sady metód metódy unblock () uzamknuté na príznak false a upozorní všetky čakajúce vlákna.
Niektoré ukazovatele, ktoré si treba pamätať na zámky:
- V prostredí Java má každý objekt zámok alebo monitor. Tento zámok je prístupný pomocou vlákna.
- Tento monitor alebo zámok môže súčasne získať iba jedno vlákno.
- Programovací jazyk Java poskytuje kľúčové slovo Synchronizované, ktoré nám umožňuje synchronizovať vlákna tak, že blok alebo metódu nastavíme ako Synchronizované.
- Zdieľané zdroje, ktoré vlákna potrebujú na prístup, sa uchovávajú v rámci tohto synchronizovaného bloku / metódy.
Mutexy v Jave
Už sme diskutovali o tom, že vo viacvláknovom prostredí môžu nastať rasy, keď sa viac ako jedno vlákno pokúsi získať prístup k zdieľaným prostriedkom súčasne a rasy majú za následok neočakávaný výstup.
Časť programu, ktorá sa pokúša získať prístup k zdieľanému prostriedku, sa nazýva „Kritická časť“ . Aby sa zabránilo výskytu závodných podmienok, je potrebné synchronizovať prístup do kritického úseku. Synchronizáciou tejto kritickej sekcie zabezpečujeme, aby ku kritickej sekcii malo prístup naraz iba jedno vlákno.
Najjednoduchším typom synchronizátora je „mutex“. Mutex zaisťuje, že v danom prípade môže kritickú sekciu vykonať iba jedno vlákno.
Mutex je podobný konceptu monitorov alebo zámkov, o ktorom sme hovorili vyššie. Ak vlákno potrebuje prístup do kritickej sekcie, musí získať mutex. Po získaní mutexu bude vlákno pristupovať ku kódu kritickej sekcie a po dokončení mutex uvoľní.
Ostatné vlákna, ktoré čakajú na prístup do kritickej sekcie, budú medzitým zablokované. Hneď ako vlákno, ktoré drží mutex, ho uvoľní, do kritickej sekcie vstúpi ďalšie vlákno.
ako používať tvrdenie v selenovom webdriveri -
Existuje niekoľko spôsobov, ako môžeme implementovať mutex v Jave.
- Používanie synchronizovaného kľúčového slova
- Pomocou Semaforu
- Používanie ReentrantLock
V tomto výučbe sa budeme zaoberať prvým prístupom, t. J. Synchronizáciou. Ďalším dvom prístupom - Semaphore a ReentrantLock sa budeme venovať v nasledujúcom tutoriále, kde sa budeme venovať súbežnému balíku Java.
Synchronizované kľúčové slovo
Java poskytuje kľúčové slovo „Synchronizované“, ktoré je možné v programe použiť na označenie kritickej sekcie. Kritickou časťou môže byť blok kódu alebo úplná metóda. K kritickej sekcii označenej kľúčovým slovom Synchronized má teda prístup iba jedno vlákno.
Môžeme napísať súbežné časti (časti, ktoré sa vykonávajú súčasne) pre aplikáciu pomocou kľúčového slova Synchronized. Závodných podmienok sa tiež zbavíme vytvorením bloku kódu alebo metódy Synchronized.
Keď označíme blok alebo metódu synchronizovanú, chránime zdieľané zdroje vo vnútri týchto entít pred súčasným prístupom, a tým pred poškodením.
Typy synchronizácie
Ako sú vysvetlené nižšie, existujú 2 typy synchronizácie:
# 1) Synchronizácia procesov
Synchronizácia procesov zahŕňa viac procesov alebo vlákien vykonávajúcich súčasne. Nakoniec sa dostanú do stavu, keď sa tieto procesy alebo vlákna zaviažu k určitej postupnosti akcií.
# 2) Synchronizácia vlákna
Pri synchronizácii vlákien sa viac ako jedno vlákno pokúša získať prístup k zdieľanému priestoru. Vlákna sú synchronizované takým spôsobom, že do zdieľaného priestoru je prístupný iba po jednom vlákne.
Synchronizácia procesov je mimo rozsahu tohto tutoriálu. Preto tu budeme diskutovať iba o synchronizácii vlákien.
V Jave môžeme použiť synchronizované kľúčové slovo s:
- Blok kódu
- Metóda
Vyššie uvedené typy sú vzájomne sa vylučujúce typy synchronizácie vlákien. Vzájomné vylúčenie zabráni vláknam, ktoré majú prístup k zdieľaným údajom, navzájom sa nerušiť.
Ďalším typom synchronizácie vlákien je „komunikácia medzi vláknami“, ktorá je založená na spolupráci medzi vláknami. Komunikácia medzi vláknami je mimo rozsahu tohto tutoriálu.
Predtým, ako pristúpime k synchronizácii blokov a metód, implementujme program Java, ktorý demonštruje správanie vlákien, ak neexistuje synchronizácia.
Viacvláknové spracovanie bez synchronizácie
Nasledujúci program Java má viac vlákien, ktoré nie sú synchronizované.
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'); } } }
Výkon
ako odstrániť prvok z poľa v jave s príkladom
Z výstupu vidíme, že keďže vlákna nie sú synchronizované, výstup je nekonzistentný. Obidve vlákna sa spustia a potom postupne zobrazia počítadlo. Na konci obidve vlákna vychádzajú.
Z daného programu malo prvé vlákno po zobrazení hodnôt počítadla skončiť a potom malo druhé vlákno začať zobrazovať hodnoty počítadla.
Teraz poďme na synchronizáciu a začneme synchronizáciou bloku kódu.
Blok synchronizovaného kódu
Synchronizovaný blok sa používa na synchronizáciu bloku kódu. Tento blok sa obvykle skladá z niekoľkých riadkov. Synchronizovaný blok sa používa, keď nechceme, aby bola synchronizovaná celá metóda.
Napríklad, máme metódu s povedzme 75 riadkami kódu. Z toho sa vyžaduje, aby sa po jednom vlákne vykonalo iba 10 riadkov kódu. V takom prípade, ak celú metódu urobíme synchronizovanú, bude to pre systém záťaž. V takýchto situáciách ideme na synchronizované bloky.
Rozsah synchronizovanej metódy je vždy menší ako rozsah synchronizovanej metódy. Synchronizovaná metóda uzamkne objekt zdieľaného prostriedku, ktorý má používať viac vlákien.
Všeobecná syntax synchronizovaného bloku je uvedená nižšie:
synchronized (lock_object){ //synchronized code statements }
Tu „lock_object“ je referenčný výraz objektu, na ktorom sa má získať zámok. Takže kedykoľvek chce vlákno získať prístup k synchronizovaným príkazom vo vnútri bloku na vykonanie, musí získať zámok na monitore ‘lock_object’.
Ako už bolo uvedené, synchronizované kľúčové slovo zaisťuje, že zámok môže získať iba jedno vlákno súčasne a všetky ostatné vlákna musia čakať, kým vlákno, ktoré drží zámok, nedokončí a neuvoľní zámok.
Poznámka
- „NullPointerException“ je vyvolaná, ak je použitý lock_object Null.
- Ak vlákno spí a stále drží zámok, zámok sa neuvoľní. Ostatné vlákna nebudú mať počas tohto režimu spánku prístup k zdieľanému objektu.
Teraz predstavíme vyššie uvedený príklad, ktorý už bol implementovaný s miernymi zmenami. V predchádzajúcom programe sme nesynchronizovali kód. Teraz použijeme synchronizovaný blok a porovnáme výstup.
Multi-threading so synchronizáciou
V programe Java uvedenom nižšie používame synchronizovaný blok. V metóde run synchronizujeme kód riadkov, ktoré tlačia počítadlo pre každé vlákno.
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'); } } }
Výkon
Teraz je výstup tohto programu pomocou synchronizovaného bloku dosť konzistentný. Podľa očakávaní sa obe vlákna začnú vykonávať. Prvé vlákno skončilo so zobrazením hodnôt počítadla a ukončí sa. Potom druhé vlákno zobrazí hodnoty počítadla a ukončí sa.
Synchronizovaná metóda
V tejto časti si povieme niečo o synchronizovanej metóde. Predtým sme videli, že môžeme označiť malý blok pozostávajúci z menej riadkov kódu za synchronizovaný blok. Ak chceme, aby bola synchronizovaná celá funkcia, potom môžeme deklarovať metódu ako synchronizovanú.
Keď je metóda synchronizovaná, bude môcť volanie metódy uskutočniť naraz iba jedno vlákno.
Všeobecná syntax pre zápis synchronizovanej metódy je:
synchronized method_name (parameters){ //synchronized code }
Rovnako ako synchronizovaný blok, aj v prípade synchronizovanej metódy potrebujeme lock_object, ktorý budú používať vlákna, ktoré pristupujú k synchronizovanej metóde.
V prípade synchronizovanej metódy môže byť objekt uzamknutia jedným z nasledujúcich spôsobov:
- Ak je synchronizovaná metóda statická, potom je objekt zámku daný objektom „.class“.
- Pre nestatickú metódu je uzamknutý objekt daný aktuálnym objektom, t. J. Tento objekt.
Zvláštnou vlastnosťou synchronizovaného kľúčového slova je to, že je znovu prihlásené. To znamená, že synchronizovaná metóda môže volať inú synchronizovanú metódu s rovnakým zámkom. Takže vlákno držiace zámok môže mať prístup k inej synchronizovanej metóde bez nutnosti získania iného zámku.
Synchronizovaná metóda je demonštrovaná na nasledujúcom príklade.
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(); } }
Výkon
Vo vyššie uvedenom programe sme použili synchronizovanú metódu na tlač štvorcov čísla. Horná hranica počtu je metóde odovzdaná ako argument. Potom počínajúc od 1 sa štvorce každého čísla tlačia, kým sa nedosiahne horná hranica.
V hlavnej funkcii sa vytvorí inštancia vlákna. Každej inštancii vlákna sa odovzdá číslo na tlač štvorcov.
Ako už bolo spomenuté vyššie, keď je metóda, ktorá sa má synchronizovať, statická, potom je do triedy zahrnutý objekt lock a nie objekt. To znamená, že sa zameriame na triedu a nie na objekt. Toto sa nazýva statická synchronizácia.
Ďalší príklad je uvedený nižšie.
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(); } }
Výkon
Vo vyššie uvedenom programe tlačíme násobiace tabuľky čísel. Každé číslo, ktorého tabuľka sa má vytlačiť, je inštanciou vlákna inej triedy vlákien. Takto tlačíme multiplikačné tabuľky 2 a 5, takže na tlač tabuliek 2 a 5 máme dve triedy thread_one a thread_two.
Stručne povedané, synchronizované kľúčové slovo Java vykonáva nasledujúce funkcie:
- Synchronizované kľúčové slovo v Jave zaručuje vzájomne výlučný prístup k zdieľaným zdrojom poskytnutím blokovacieho mechanizmu. Zamknutie tiež zabráni pretekovým podmienkam.
- Použitím synchronizovaného kľúčového slova zabraňujeme súbežným programovacím chybám v kóde.
- Keď je metóda alebo blok deklarovaná ako synchronizovaná, potom vlákno potrebuje na vstup do synchronizovanej metódy alebo bloku výlučný zámok. Po vykonaní potrebných akcií vlákno uvoľní zámok a vyprázdni operáciu zápisu. Týmto spôsobom sa odstránia chyby pamäte spojené s nekonzistentnosťou.
Prchavé v Jave
Prchavé kľúčové slovo v Jave sa používa na zaistenie bezpečia tried pre vlákna. Na úpravu hodnoty premennej o rôzne vlákna používame aj volatile kľúčové slovo. Prchavé kľúčové slovo možno použiť na deklaráciu premennej s primitívnymi typmi aj s objektmi.
V určitých prípadoch sa volatilné kľúčové slovo používa ako alternatíva k synchronizovanému kľúčovému slovu. Upozorňujeme však, že nejde o náhradu za synchronizované kľúčové slovo.
Keď je premenná vyhlásená za volatilnú, jej hodnota sa nikdy neukladá do vyrovnávacej pamäte, ale vždy sa číta z hlavnej pamäte. Nestála premenná zaručuje usporiadanie a viditeľnosť. Aj keď možno premennú vyhlásiť za volatilnú, nemôžeme deklarovať triedy alebo metódy ako volatilné.
Zvážte nasledujúci blok kódu:
class ABC{ static volatile int myvar =10; }
Vo vyššie uvedenom kóde je premenná myvar statická a volatilná. Statická premenná je zdieľaná medzi všetkými objektmi triedy. Nestála premenná sa vždy nachádza v hlavnej pamäti a nikdy sa do vyrovnávacej pamäte neukladá.
Z tohto dôvodu bude v hlavnej pamäti iba jedna kópia myvaru a všetky akcie čítania a zápisu sa na tejto premennej vykonajú z hlavnej pamäte. Ak by myvar nebol deklarovaný ako volatilný, potom by mal každý objekt vlákna inú kópiu, ktorá by viedla k nekonzistenciám.
Niektoré z rozdielov medzi prchavými a synchronizovanými kľúčovými slovami sú uvedené nižšie.
Prchavé kľúčové slovo | Synchronizované kľúčové slovo |
---|---|
Prchavé kľúčové slovo sa používa iba s premennými. | Synchronizované kľúčové slovo sa používa s kódovými blokmi a metódami. |
Prchavé kľúčové slovo nemôže blokovať vlákno na čakanie. | Synchronizované kľúčové slovo môže blokovať vlákno na čakanie. |
Výkon vlákna sa zlepšuje vďaka Volatile. | Výkon vlákna sa pri synchronizácii trochu zhoršuje. |
Prchavé premenné sa nachádzajú v hlavnej pamäti. | Synchronizované konštrukty sa nenachádzajú v hlavnej pamäti. |
Volatile synchronizuje jednu premennú medzi pamäťou vlákien a hlavnou pamäťou súčasne. | Synchronizované kľúčové slovo synchronizuje všetky premenné naraz. |
Zablokovanie v Jave
Videli sme, že môžeme synchronizovať viac vlákien pomocou synchronizovaného kľúčového slova a zaistiť, aby boli programy bezpečné pre vlákna. Synchronizáciou vlákien zabezpečíme, aby sa viaceré vlákna vykonávali súčasne v prostredí s viacerými vláknami.
Niekedy však nastane situácia, že vlákna už nebudú môcť fungovať súčasne. Namiesto toho čakajú donekonečna. K tomu dôjde, keď jedno vlákno čaká na zdroj a tento zdroj je blokovaný druhým vláknom.
Druhé vlákno naopak čaká na zdroj blokovaný prvým vláknom. Takáto situácia vedie k „uviaznutiu“ v Jave.
Zablokovanie v Jave je znázornené na obrázku nižšie.
Ako vidíme z vyššie uvedeného diagramu, vlákno A uzamklo zdroj r1 a čaká na zdroj r2. Vlákno B na druhej strane zablokovalo prostriedok r2 a čaká na r1.
Žiadne z vlákien teda nemôže dokončiť svoje vykonávanie, pokiaľ nezachytia čakajúce zdroje. Táto situácia vyústila do slepej uličky, kde obe vlákna nekonečne čakajú na zdroje.
Nižšie je uvedený príklad zablokovania v Jave.
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(); } }
Výkon
Vo vyššie uvedenom programe máme dva zdieľané zdroje a dve vlákna. Obidve vlákna sa pokúšajú získať prístup k zdieľaným zdrojom jeden po druhom. Výstup ukazuje, že obe vlákna blokujú jeden zdroj, zatiaľ čo čakajú na ostatné. Vzniká tak slepá situácia.
Aj keď nemôžeme zabrániť úplnému zablokovaniu, môžeme sa im určite vyhnúť podniknutím určitých krokov.
Nižšie sú uvedené prostriedky, pomocou ktorých sa môžeme vyhnúť zablokovaniu v prostredí Java.
# 1) Vyhýbaním sa vnoreným zámkom
Vnorené zámky sú najdôležitejším dôvodom zablokovania. Vnorené zámky sú zámky, ktoré sú pridelené viacerým vláknam. Preto by sme sa mali vyhnúť zámkom viac ako jednej nite.
# 2) Použite vlákno Pripojiť sa
Mali by sme používať Thread.join s maximálnym časom, aby vlákna mohli využiť maximálny čas na vykonanie. Tým sa zabráni zablokovaniu, ku ktorému väčšinou dochádza, keď jedno vlákno neustále čaká na ďalšie.
# 3) Vyhnite sa zbytočnému blokovaniu
Mali by sme zamknúť iba potrebný kód. Zbytočné zámky kódu môžu viesť k zablokovaniu programu. Pretože uviaznutia môžu narušiť kód a brániť priebehu programu, mali by sme tendenciu vyhnúť sa uviaznutiu v našich programoch.
často kladené otázky
Otázka č. 1) Čo je to synchronizácia a prečo je dôležitá?
Odpoveď: Synchronizácia je proces riadenia prístupu zdieľaného zdroja k viacerým vláknam. Bez synchronizácie môže viac vlákien aktualizovať alebo meniť zdieľaný prostriedok súčasne, čo vedie k nekonzistenciám.
Mali by sme teda zabezpečiť, aby sa v prostredí s viacerými vláknami vlákna synchronizovali tak, aby sa spôsob, akým pristupujú k zdieľaným zdrojom, vzájomne vylučoval a bol konzistentný.
Otázka 2) Čo je to synchronizácia a nesynchronizácia v prostredí Java?
Odpoveď: Synchronizácia znamená, že konštrukcia je bezpečná pre vlákna. To znamená, že viac vlákien nemôže získať prístup ku konštrukcii (blok kódu, metóda atď.) Naraz.
Nesynchronizované konštrukcie nie sú bezpečné pre vlákna. K nesynchronizovaným metódam alebo blokom môže kedykoľvek získať prístup viac vlákien. Populárnou nesynchronizovanou triedou v Jave je StringBuilder.
Otázka č. 3) Prečo je vyžadovaná synchronizácia?
Odpoveď: Keď je potrebné procesy vykonávať súčasne, potrebujeme synchronizáciu. Je to tak preto, lebo potrebujeme zdroje, ktoré môžu byť zdieľané medzi mnohými procesmi.
Aby sme sa vyhli stretom medzi procesmi alebo vláknami pri prístupe k zdieľaným prostriedkom, musíme tieto prostriedky synchronizovať, aby všetky vlákna získali prístup k prostriedkom a aplikácia tiež bežala hladko.
Otázka č. 4) Ako získate zoznam Synchronized ArrayList?
Odpoveď: Môžeme použiť metódu Collections.synchronized list s ArrayList ako argument na prevedenie ArrayList na synchronizovaný zoznam.
Otázka č. 5) Je HashMap synchronizovaná?
rozdiel medzi implicitným a explicitným čakaním v seléne
Odpoveď: Nie, HashMap nie je synchronizovaný, ale HashTable je synchronizovaný.
Záver
V tomto výučbe sme podrobne diskutovali o synchronizácii vlákien. Spolu s ním sme sa tiež dozvedeli o volatilnom kľúčovom slove a zablokovaní v Jave. Synchronizácia pozostáva zo synchronizácie procesov a vlákien.
V prostredí viacerých vlákien sa viac zaoberáme synchronizáciou vlákien. Videli sme tu synchronizovaný prístup k kľúčovým slovám synchronizácie vlákien.
Zablokovanie je situácia, keď viaceré vlákna nekonečne čakajú na zdroje. Videli sme príklad zablokovania v prostredí Java spolu s metódami, ako sa vyhnúť zablokovaniu v prostredí Java.
=> Navštívte tu a dozviete sa Java od začiatku.
Odporúčané čítanie
- Thread.Sleep () - Metóda Thread Sleep () v Jave s príkladmi
- Vlákna Java s metódami a životným cyklom
- Základy jazyka Java: Java Syntax, trieda Java a základné koncepty Java
- Multithreading v Jave - návod s príkladmi
- Multithreading v C ++ s príkladmi
- Výukový program JAVA pre začiatočníkov: viac ako 100 praktických výučbových programov Java Video
- Komponenty Java: Java Platform, JDK, JRE a Java Virtual Machine
- Výukový program pre Java String Metódy reťazca Java s príkladmi