Vícevláknové programy se mohou často dostat do situace, kdy se více vláken pokouší o přístup ke stejným zdrojům a nakonec produkují chybné a nepředvídané výsledky.
Proč používat synchronizaci Java?
Synchronizace Java se používá k zajištění toho, aby určitým způsobem synchronizace bylo zajištěno, že pouze jedno vlákno může v daném okamžiku přistupovat ke zdroji.
Rozvržení mřížky
Java synchronizované bloky
Java poskytuje způsob vytváření vláken a synchronizace jejich úloh pomocí synchronizovaných bloků.
Synchronizovaný blok v Javě je synchronizován na nějakém objektu. Všechny synchronizované bloky se synchronizují na stejném objektu a může v nich být současně spuštěno pouze jedno vlákno. Všechna ostatní vlákna pokoušející se vstoupit do synchronizovaného bloku jsou blokována, dokud vlákno uvnitř synchronizovaného bloku neopustí blok.
Poznámka: Synchronizované bloky v Javě jsou označeny klíčovým slovem synchronized.
Obecná 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 }> Tato synchronizace je implementována v Javě pomocí konceptu zvaného monitory nebo zámky. V daném okamžiku může vlastnit monitor pouze jedno vlákno. Když vlákno získá zámek, říká se, že vstoupilo do monitoru. Všechna ostatní vlákna, která se pokoušejí vstoupit do uzamčeného monitoru, budou pozastavena, dokud první vlákno neopustí monitor.
Typy synchronizace
V Javě jsou dvě níže uvedené synchronizace:
- Synchronizace procesu
- Synchronizace vláken
1. Synchronizace procesů v Javě
Synchronizace procesů je technika používaná ke koordinaci provádění více procesů. Zajišťuje, že sdílené zdroje jsou bezpečné a v pořádku.
2. Synchronizace vláken v Javě
Synchronizace vláken se používá ke koordinaci a řazení provádění vláken ve vícevláknovém programu. Níže jsou uvedeny dva typy synchronizace vláken:
- Vzájemná exkluzivita
- Spolupráce (mezivláknová komunikace v Javě)
Vzájemná exkluzivita
Mutual Exclusive pomáhá zabránit tomu, aby se vlákna vzájemně rušila při sdílení dat. Níže jsou uvedeny tři typy vzájemné exkluzivity:
- Synchronizovaná metoda.
- Synchronizovaný blok.
- Statická synchronizace.
Příklad synchronizace
Níže je uvedena implementace synchronizace Java:
Jáva
návrhový vzor stavitele
// 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'>);> >}> >}> }> |
>
rolovací kolečko nefunguje
>Výstup
hodnota řetězce
Sending Hi Hi Sent Sending Bye Bye Sent>
Výstup je stejný při každém spuštění programu.
Vysvětlení
Ve výše uvedeném příkladu jsme zvolili synchronizaci objektu Sender uvnitř metody run() třídy ThreadedSend. Alternativně bychom mohli definovat celý blok send() jako synchronizovaný , produkující stejný výsledek. Potom nemusíme synchronizovat objekt Message uvnitř metody run() ve třídě 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'); } }> Nemusíme vždy synchronizovat celou metodu. Někdy je to výhodnější synchronizovat pouze část metody . Java synchronizované bloky uvnitř metod to umožňují.
// 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'); } } }> Příklad synchronizované metody pomocí anonymní třídy
Jáva
// 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();> >}> }> |
řetězec tokenizer java
>
>Výstup
16 17 18 31 32 33>