Guida completa alla sincronizzazione in Java

Pubblicato: 2022-05-20

Prima di spiegare la sincronizzazione in Java , dobbiamo rivisitare brevemente il concetto di multithreading. La funzione multithreading di Java consente l'esecuzione simultanea di due o più parti di un programma per il massimo utilizzo della CPU. Ogni parte di un tale programma è un thread e i thread sono processi leggeri all'interno di un processo.

Ora, più thread di un programma potrebbero tentare di accedere alle stesse risorse e produrre risultati imprecisi. Quindi, deve esserci una certa sincronizzazione per garantire che solo un thread abbia accesso alle risorse in un determinato momento.

Questa guida su cos'è la sincronizzazione in Java esplorerà il concetto di sincronizzazione in dettaglio con esempi.

Sommario

Che cos'è la sincronizzazione in Java?

La sincronizzazione Java è la capacità di controllare l'accesso di più thread a una risorsa condivisa. È utile quando i programmi Java multi-thread tentano di accedere alla stessa risorsa e producono risultati errati. Utilizzando la funzione di sincronizzazione Java, solo un singolo thread può accedere alla risorsa in un determinato momento.

Java fornisce un modo per sincronizzare l'attività dei thread utilizzando blocchi sincronizzati che si sincronizzano sullo stesso oggetto e possono avere un solo thread in esecuzione al loro interno alla volta. Questi blocchi sono contrassegnati con la parola chiave sincronizzata, bloccando qualsiasi altro thread che tenta di entrare nel blocco sincronizzato fino a quando il thread già all'interno del blocco termina la sua esecuzione e lascia il blocco.

La sintassi per scrivere un blocco sincronizzato

La sintassi generale per scrivere un blocco sincronizzato in Java è la seguente:

sincronizzato( lockObject )

{

// istruzioni sincronizzate

}

Nella sintassi precedente, lockObject si riferisce a un oggetto il cui lock è correlato agli elementi sincronizzati. Ora, questo ci porta al concetto di blocco in Java.

Si blocca in Java

La sincronizzazione in Java è costruita attorno al blocco o al monitor. Ogni oggetto ha un lucchetto associato. Idealmente, un thread che richiede l'accesso ai campi di un oggetto deve prima ottenere il blocco dell'oggetto. Il blocco è un meccanismo di sincronizzazione dei thread più sofisticato e flessibile rispetto al blocco di sincronizzazione. È definito all'interno del pacchetto java.util.concurrent.lock contenente ampie implementazioni di blocco.

Impara i corsi di sviluppo software online dalle migliori università del mondo. Guadagna programmi Executive PG, programmi di certificazione avanzati o programmi di master per accelerare la tua carriera.

Metodo sincronizzato Java

Lo scopo di un metodo sincronizzato Java è bloccare gli oggetti per le risorse condivise. Pertanto, quando i thread invocano un metodo sincronizzato, il metodo ottiene automaticamente il blocco per quell'oggetto e lo rilascia una volta che il thread ha eseguito il proprio lavoro.

Ecco un esempio di metodo sincronizzato Java:

//esempio di metodo sincronizzato con java

tabella di classe{

sync void printTable(int n){//metodo sincronizzato

for(int i=1;i<=5;i++){

System.out.println(n*i);

Tentativo{

Thread.sleep(400);

}catch(Eccezione e){System.out.println(e);}

}

}

}

la classe MyThread1 estende Thread{

Tavoletta;

MyThread1(Tabella t){

questo.t=t;

}

esecuzione vuota pubblica(){

t.printTable(5);

}

}

la classe MyThread2 estende Thread{

Tavoletta;

MyThread2(Tabella t){

questo.t=t;

}

esecuzione vuota pubblica(){

t.printTable(100);

}

}

public class TestSynchronization2{

public static void main(String args[]){

Table obj = new Table();//solo un oggetto

MyThread1 t1=nuovo MyThread1(obj);

MyThread2 t2=nuovo MyThread2(obj);

t1.inizio();

t2.inizio();

}

}

Produzione:

5

10

15

20

25

100

200

300

400

500

Cosa succede senza sincronizzazione?

Ora, diamo un'occhiata al programma precedente senza sincronizzazione (notare l'assenza della parola chiave sincronizzata).

tabella di classe{

void printTable(int n){//metodo non sincronizzato

for(int i=1;i<=5;i++){

System.out.println(n*i);

Tentativo{

Thread.sleep(400);

}catch(Eccezione e){System.out.println(e);}

}

}

}

la classe MyThread1 estende Thread{

Tavoletta;

MyThread1(Tabella t){

questo.t=t;

}

esecuzione vuota pubblica(){

t.printTable(5);

}

}

la classe MyThread2 estende Thread{

Tavoletta;

MyThread2(Tabella t){

questo.t=t;

}

esecuzione vuota pubblica(){

t.printTable(100);

}

}

classe TestSynchronization1{

public static void main(String args[]){

Table obj = new Table();//solo un oggetto

MyThread1 t1=nuovo MyThread1(obj);

MyThread2 t2=nuovo MyThread2(obj);

t1.inizio();

t2.inizio();

}

}

Produzione:

5

100

10

200

15

300

20

400

25

500

Come puoi vedere, l'output è incoerente senza sincronizzazione.

Esplora i nostri corsi di ingegneria del software popolari

SL. No Programmi di sviluppo software
1 Master of Science in Informatica presso LJMU e IIITB Programma di certificazione di sicurezza informatica Caltech CME
2 Bootcamp di sviluppo full stack Programma PG in Blockchain
3 Executive Post Graduate Program in Software Development - Specializzazione in DevOps Visualizza tutti i corsi di ingegneria del software

Tipi di sincronizzazione in Java

Per rispondere a cos'è la sincronizzazione dei thread in Java , sono disponibili due tipi di sincronizzazione: la sincronizzazione dei thread e la sincronizzazione dei processi.

Capiamo cosa significa ciascuno.

Sincronizzazione dei thread: quando più thread tentano di accedere a una risorsa condivisa, è necessario assicurarsi che la risorsa venga utilizzata da un solo thread alla volta. La sincronizzazione dei thread è il processo che consente a un solo thread di utilizzare la risorsa condivisa quando più thread tentano di utilizzare la risorsa contemporaneamente.

Sincronizzazione dei processi: si riferisce all'esecuzione simultanea di più processi per raggiungere uno stato in cui i processi si impegnano a un ordine di esecuzione appropriato. La sincronizzazione dei processi è necessaria quando due o più processi cooperano e l'esecuzione di un processo influisce sull'altro. Pertanto, la sincronizzazione dei processi elimina la possibilità di output imprecisi e garantisce il corretto ordine di esecuzione.

Metodi di sincronizzazione in Java

In generale, ci sono quattro metodi di sincronizzazione in Java:

  • Metodi statici sincronizzati
  • Metodi di istanza sincronizzati
  • Blocco sincronizzato all'interno di metodi statici
  • Blocco sincronizzato all'interno dei metodi di istanza

Diamo un'occhiata a ciascun metodo di sincronizzazione Java in modo più dettagliato.

Metodi statici sincronizzati

Qui, utilizziamo la parola chiave sincronizzata per contrassegnare i metodi statici in Java. Ecco un esempio di metodo statico sincronizzato con Java:

MyStaticCounter pubblico statico {

conteggio int statico privato = 0;

public statico sincronizzato void incremento (valore int) {

conteggio += valore;

}

}

Metodi di istanza sincronizzati

Quando si utilizza un blocco sincronizzato con metodi di istanza, ogni oggetto ha il proprio metodo sincronizzato. Ogni oggetto può avere un solo thread che può essere eseguito all'interno di un metodo. Se sono presenti più oggetti, un singolo thread può essere eseguito per ogni oggetto all'interno del blocco.

classe pubblica MyCounter {

conteggio int privato = 0;

incremento del vuoto sincronizzato pubblico (valore int) {

this.count += valore;

}

decremento vuoto sincronizzato pubblico (valore int) {

questo.conteggio -= valore;

}

}

Blocco sincronizzato all'interno di metodi statici

Di seguito è riportato un esempio in cui utilizziamo un blocco sincronizzato all'interno di un metodo statico:

classe pubblica MyClass {

stampa vuota statica pubblica (messaggio stringa) {

sincronizzato(MyClass.class) {

log.writeln(messaggio);

}

}

}

Blocco sincronizzato all'interno dei metodi di istanza

Invece di sincronizzare l'intero metodo, possiamo utilizzare sincronizzato su un blocco specifico all'interno del metodo. Di seguito è riportato un esempio di un blocco di codice sincronizzato all'interno di un metodo non sincronizzato:

incremento vuoto pubblico (valore int) {

sincronizzato(questo) {

this.count += valore;

}

}

Necessità di sincronizzazione in Java

Ora che sai cos'è la sincronizzazione in Java , potresti chiederti perché lo usiamo in primo luogo.

La parola chiave sincronizzata Java fornisce funzionalità essenziali per la programmazione simultanea. Ecco come aiuta la sincronizzazione in Java:

  • La sincronizzazione Java fornisce la funzione di blocco per eliminare qualsiasi race condition tra i thread e garantire l'accesso mutuamente esclusivo alla risorsa condivisa.
  • Il blocco sincronizzato Java fornisce sia le funzioni di blocco che di sblocco. Pertanto, un thread deve acquisire il blocco prima di immettere un metodo o un blocco sincronizzato.
  • La parola chiave sincronizzata impedisce il riordino delle istruzioni del programma da parte del compilatore.

Conclusione

Riassumendo, la sincronizzazione in Java assicura che un solo thread alla volta possa accedere alla risorsa condivisa. Possiamo sincronizzare un blocco o un metodo utilizzando la parola chiave sincronizzata Java. Quando un thread vuole entrare in un blocco sincronizzato, deve acquisire un blocco e, dopo aver lasciato il blocco, il thread rilascia il blocco. Possiamo usare la parola chiave sincronizzata sia con i metodi che all'interno del blocco di un metodo.

Ti chiedi dove imparare Java?

Certificazione PG collegata al lavoro di upGrad in ingegneria del software è quello che stai cercando!

Appositamente progettata per neolaureati e ultimi anni, la certificazione PG collegata al lavoro di upGrad in Ingegneria del software è perfetta per coloro che vogliono imparare a programmare e ottenere posti in ruoli software di livello base. Questo programma online di 5 mesi insegnerà le migliori competenze software come Java, JavaScript, HTML5, DSA, AWS, MERN e altro!

D: Perché utilizziamo sincronizzato in Java?

R: La parola chiave sincronizzata in Java garantisce che un solo thread alla volta possa accedere alle risorse condivise. È utile quando i programmi Java multithread tentano di accedere alla stessa risorsa e producono risultati imprecisi.

D: Come viene implementata la sincronizzazione in Java?

R: Java implementa la sincronizzazione usando il concetto di monitor con un solo thread che possiede un monitor in un dato momento. Quando un thread acquisisce un blocco, ottiene l'accesso al monitor e tutti gli altri thread che tentano di accedere al monitor bloccato rimangono bloccati finché il primo thread non lascia il monitor.

D: Che cos'è un deadlock in Java?

R: Java deadlock si verifica quando un thread è in attesa di un blocco oggetto, ma un altro thread lo acquisisce e il secondo thread è in attesa di un blocco oggetto acquisito dal primo. Pertanto, entrambi i thread attendono l'un l'altro per rilasciare il blocco, determinando un deadlock.