logo

Sincronització en Java

Sovint, els programes multifils poden arribar a una situació en què diversos fils intenten accedir als mateixos recursos i finalment produeixen resultats erronis i imprevistos.

Per què utilitzar la sincronització de Java?

La sincronització de Java s'utilitza per assegurar-se mitjançant algun mètode de sincronització que només un fil pot accedir al recurs en un moment determinat.



cadena de concat java

Blocs sincronitzats de Java

Java ofereix una manera de crear fils i sincronitzar les seves tasques mitjançant blocs sincronitzats.

Un bloc sincronitzat a Java es sincronitza en algun objecte. Tots els blocs sincronitzats es sincronitzen en el mateix objecte i només poden tenir un fil executat dins d'ells alhora. Tots els altres fils que intenten entrar al bloc sincronitzat es bloquegen fins que el fil dins del bloc sincronitzat surt del bloc.

Nota: Els blocs sincronitzats a Java es marquen amb la paraula clau sincronitzada.



Forma general de bloc sincronitzat

// 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 }>

Aquesta sincronització s'implementa a Java amb un concepte anomenat monitors o bloquejos. Només un fil pot tenir un monitor en un moment determinat. Quan un fil adquireix un bloqueig, es diu que ha entrat al monitor. Tots els altres fils que intentin entrar al monitor bloquejat seran suspesos fins que el primer fil surti del monitor.

Tipus de sincronització

Hi ha dues sincronitzacions a Java esmentades a continuació:

  1. Sincronització de processos
  2. Sincronització de fils

1. Sincronització de processos en Java

La sincronització de processos és una tècnica utilitzada per coordinar l'execució de múltiples processos. Assegura que els recursos compartits estiguin segurs i en ordre.



2. Sincronització de fils en Java

La sincronització de fils s'utilitza per coordinar i ordenar l'execució dels fils en un programa multifils. Hi ha dos tipus de sincronització de fils que s'esmenten a continuació:

  • Exclusivitat mútua
  • Cooperació (comunicació entre fils en Java)

Exclusivitat mútua

L'exclusivitat mútua ajuda a evitar que els fils interfereixin entre si mentre comparteixen dades. Hi ha tres tipus d'exclusivitat mútua que s'esmenten a continuació:

  • Mètode sincronitzat.
  • Bloc sincronitzat.
  • Sincronització estàtica.

Exemple de sincronització

A continuació es mostra la implementació de la sincronització de Java:

Java

decodificació js base64




// 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'>);> >}> >}> }>

>

alfabet per nombre

>

Sortida

llançar llançaments en java
Sending Hi Hi Sent Sending Bye Bye Sent>

La sortida és la mateixa cada vegada que executem el programa.

Explicació

A l'exemple anterior, optem per sincronitzar l'objecte Sender dins del mètode run() de la classe ThreadedSend. Alternativament, podríem definir el tot el bloc send() sincronitzat , produint el mateix resultat. Aleshores, no hem de sincronitzar l'objecte Message dins del mètode run() a la classe 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'); } }>

No sempre hem de sincronitzar tot un mètode. De vegades és preferible sincronitzar només una part d'un mètode . Els blocs sincronitzats de Java dins dels mètodes ho fan possible.

// 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'); } } }>

Exemple del mètode sincronitzat utilitzant una classe anònima

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();> >}> }>

dormir en js

>

>

Sortida

16 17 18 31 32 33>