Viacvláknové programy sa môžu často dostať do situácie, keď sa viaceré vlákna pokúšajú o prístup k rovnakým zdrojom a nakoniec produkujú chybné a nepredvídané výsledky.
Prečo používať synchronizáciu Java?
Synchronizácia Java sa používa na to, aby sa pomocou určitej metódy synchronizácie uistilo, že k zdroju môže v danom čase pristupovať iba jedno vlákno.
java while podmienka
Java synchronizované bloky
Java poskytuje spôsob vytvárania vlákien a synchronizácie ich úloh pomocou synchronizovaných blokov.
Synchronizovaný blok v jazyku Java je synchronizovaný na nejakom objekte. Všetky synchronizované bloky sa synchronizujú na rovnakom objekte a môžu mať v sebe spustené iba jedno vlákno naraz. Všetky ostatné vlákna, ktoré sa pokúšajú vstúpiť do synchronizovaného bloku, sú zablokované, kým vlákno vo vnútri synchronizovaného bloku neopustí blok.
Poznámka: Synchronizované bloky v Jave sú označené kľúčovým slovom synchronizované.
Všeobecná forma synchronizovaného bloku
// Only one thread can execute at a time. // sync_object is a reference to an object // whose lock associates with the monitor . // The code is said to be synchronized on // the monitor object synchronized(sync_object) { // Access shared variables and other // shared resources }> Táto synchronizácia je implementovaná v jazyku Java s konceptom nazývaným monitory alebo zámky. V danom čase môže vlastniť monitor iba jedno vlákno. Keď vlákno získa zámok, hovorí sa, že vstúpilo do monitora. Všetky ostatné vlákna, ktoré sa pokúsia vstúpiť na uzamknutý monitor, budú pozastavené, kým prvé vlákno neopustí monitor.
Typy synchronizácie
V Jave sú uvedené dve synchronizácie:
- Synchronizácia procesov
- Synchronizácia vlákien
1. Synchronizácia procesov v jazyku Java
Synchronizácia procesov je technika používaná na koordináciu vykonávania viacerých procesov. Zabezpečuje, že zdieľané zdroje sú bezpečné a v poriadku.
2. Synchronizácia vlákien v jazyku Java
Synchronizácia vlákien sa používa na koordináciu a usporiadanie vykonávania vlákien vo viacvláknovom programe. Nižšie sú uvedené dva typy synchronizácie vlákien:
- Vzájomná exkluzívnosť
- Spolupráca (medzivláknová komunikácia v jazyku Java)
Vzájomná exkluzívnosť
Vzájomné exkluzívne pomáha zabrániť tomu, aby sa vlákna navzájom rušili pri zdieľaní údajov. Nižšie sú uvedené tri typy vzájomnej exkluzivity:
- Synchronizovaná metóda.
- Synchronizovaný blok.
- Statická synchronizácia.
Príklad synchronizácie
Nižšie je uvedená implementácia synchronizácie Java:
Java
java lambda výrazy
// A Java program to demonstrate working of> // synchronized.> import> java.io.*;> import> java.util.*;> // A Class used to send a message> class> Sender {> >public> void> send(String msg)> >{> >System.out.println(>'Sending '> + msg);> >try> {> >Thread.sleep(>1000>);> >}> >catch> (Exception e) {> >System.out.println(>'Thread interrupted.'>);> >}> >System.out.println(>'
'> + msg +>'Sent'>);> >}> }> // Class for send a message using Threads> class> ThreadedSend>extends> Thread {> >private> String msg;> >Sender sender;> >// Receives a message object and a string> >// message to be sent> >ThreadedSend(String m, Sender obj)> >{> >msg = m;> >sender = obj;> >}> >public> void> run()> >{> >// Only one thread can send a message> >// at a time.> >synchronized> (sender)> >{> >// synchronizing the send object> >sender.send(msg);> >}> >}> }> // Driver class> class> SyncDemo {> >public> static> void> main(String args[])> >{> >Sender send =>new> Sender();> >ThreadedSend S1 =>new> ThreadedSend(>' Hi '>, send);> >ThreadedSend S2 =>new> ThreadedSend(>' Bye '>, send);> >// Start two threads of ThreadedSend type> >S1.start();> >S2.start();> >// wait for threads to end> >try> {> >S1.join();> >S2.join();> >}> >catch> (Exception e) {> >System.out.println(>'Interrupted'>);> >}> >}> }> |
>
'kruskalov algoritmus'
>Výkon
mysql zoznam všetkých používateľov
Sending Hi Hi Sent Sending Bye Bye Sent>
Výstup je rovnaký pri každom spustení programu.
Vysvetlenie
Vo vyššie uvedenom príklade sme sa rozhodli synchronizovať objekt Sender v metóde run() triedy ThreadedSend. Alternatívne by sme mohli definovať celý blok send() ako synchronizovaný , produkujúce rovnaký výsledok. Potom nemusíme synchronizovať objekt Message v metóde run() v triede ThreadedSend.
// An alternate implementation to demonstrate // that we can use synchronized with method also. class Sender { public synchronized void send(String msg) { System.out.println('Sending ' + msg); try { Thread.sleep(1000); } catch (Exception e) { System.out.println('Thread interrupted.'); } System.out.println('
' + msg + 'Sent'); } }> Nie vždy musíme synchronizovať celú metódu. Niekedy je to výhodnejšie synchronizovať iba časť metódy . Umožňujú to synchronizované bloky Java vo vnútri metód.
// One more alternate implementation to demonstrate // that synchronized can be used with only a part of // method class Sender { public void send(String msg) { synchronized(this) { System.out.println('Sending ' + msg ); try { Thread.sleep(1000); } catch (Exception e) { System.out.println('Thread interrupted.'); } System.out.println('
' + msg + 'Sent'); } } }> Príklad synchronizovanej metódy pomocou anonymnej triedy
Java
// Java Pogram to synchronized method by> // using an anonymous class> import> java.io.*;> class> Test {> >synchronized> void> test_function(>int> n)> >{> >// synchronized method> >for> (>int> i =>1>; i <=>3>; i++) {> >System.out.println(n + i);> >try> {> >Thread.sleep(>500>);> >}> >catch> (Exception e) {> >System.out.println(e);> >}> >}> >}> }> // Driver Class> public> class> GFG {> >// Main function> >public> static> void> main(String args[])> >{> >// only one object> >final> Test obj =>new> Test();> >Thread a =>new> Thread() {> >public> void> run() { obj.test_function(>15>); }> >};> >Thread b =>new> Thread() {> >public> void> run() { obj.test_function(>30>); }> >};> >a.start();> >b.start();> >}> }> |
iterátor java mapa
>
>Výkon
16 17 18 31 32 33>