Synkronisering i Java

Flertrådede programmer kan ofte komme til en situasjon der flere tråder prøver å få tilgang til de samme ressursene og til slutt produserer feilaktige og uforutsette resultater.

Hvorfor bruke Java-synkronisering?

Java-synkronisering brukes til å sikre ved hjelp av en synkroniseringsmetode at bare én tråd kan få tilgang til ressursen på et gitt tidspunkt.

Java-synkroniserte blokker

Java gir en måte å lage tråder og synkronisere oppgavene deres ved å bruke synkroniserte blokker.

En synkronisert blokk i Java er synkronisert på et objekt. Alle synkroniserte blokker synkroniseres på det samme objektet og kan bare ha én tråd utført i seg om gangen. Alle andre tråder som forsøker å gå inn i den synkroniserte blokken blir blokkert til tråden inne i den synkroniserte blokken går ut av blokken.

Merk: Synkroniserte blokker i Java er merket med det synkroniserte nøkkelordet.

Generell form for synkronisert blokk

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

Denne synkroniseringen er implementert i Java med et konsept som kalles monitorer eller låser. Bare én tråd kan eie en skjerm på et gitt tidspunkt. Når en tråd får en lås, sies det å ha kommet inn i monitoren. Alle andre tråder som forsøker å gå inn i den låste skjermen vil bli suspendert til den første tråden går ut av skjermen.

Typer synkronisering

Det er to synkroniseringer i Java nevnt nedenfor:

  1. Prosesssynkronisering
  2. Trådsynkronisering

1. Prosesssynkronisering i Java

Prosesssynkronisering er en teknikk som brukes til å koordinere utførelsen av flere prosesser. Det sikrer at de delte ressursene er trygge og i orden.

2. Trådsynkronisering i Java

Trådsynkronisering brukes til å koordinere og bestille utføringen av trådene i et flertråds program. Det er to typer trådsynkronisering som er nevnt nedenfor:

  • Gjensidig eksklusiv
  • Samarbeid (intertrådkommunikasjon i Java)

Gjensidig eksklusiv

Mutual Exclusive hjelper til med å forhindre at tråder forstyrrer hverandre mens de deler data. Det er tre typer Mutual Exclusive nevnt nedenfor:

  • Synkronisert metode.
  • Synkronisert blokk.
  • Statisk synkronisering.

Eksempel på synkronisering

Nedenfor er implementeringen av Java Synchronization:

Java




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

Produksjon

Sending Hi Hi Sent Sending Bye Bye Sent 

Utgangen er den samme hver gang vi kjører programmet.

Forklaring

I eksemplet ovenfor velger vi å synkronisere Sender-objektet inne i run()-metoden til ThreadedSend-klassen. Alternativt kan vi definere hele send()-blokken som synkronisert , gir samme resultat. Da trenger vi ikke å synkronisere Message-objektet inne i run()-metoden i ThreadedSend-klassen.

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

Vi trenger ikke alltid å synkronisere en hel metode. Noen ganger er det å foretrekke synkronisere bare en del av en metode . Java-synkroniserte blokker inne i metoder gjør dette mulig.

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

Eksempel på synkronisert metode ved å bruke en anonym klasse

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

Produksjon

16 17 18 31 32 33