Cosa significa "sincronizzato"?


994

Ho alcune domande sull'uso e sul significato della synchronizedparola chiave.

  • Qual è il significato della synchronizedparola chiave?
  • Quando dovrebbero essere i metodi synchronized?
  • Cosa significa programmaticamente e logicamente?


1
utile discussione tra hashmap e tabella hash, e la sincronizzazione: stackoverflow.com/questions/40471/java-hashmap-vs-hashtable
LIMC


1
Ho esaminato l'intero link della documentazione dal primo commento e non ho capito fino a quando non sono arrivato all'ultimo paragrafo. Invece di incollare i collegamenti e non citare nulla, potrebbe essere incollare i collegamenti e aggiungere un preventivo è più utile.
Rakib,

Risposte:


878

La synchronizedparola chiave riguarda thread diversi che leggono e scrivono nelle stesse variabili, oggetti e risorse. Questo non è un argomento banale in Java, ma ecco una citazione da Sun:

synchronized i metodi consentono una semplice strategia per prevenire l'interferenza del thread e gli errori di coerenza della memoria: se un oggetto è visibile a più di un thread, tutte le letture o scritture nelle variabili di quell'oggetto vengono eseguite tramite metodi sincronizzati.

In poche parole: quando hai due thread che leggono e scrivono nella stessa 'risorsa', dì una variabile denominata foo, devi assicurarti che questi thread accedano alla variabile in modo atomico. Senza la synchronizedparola chiave, il tuo thread 1 potrebbe non vedere il thread di modifica 2 fatto foo, o peggio, potrebbe essere cambiato solo per metà. Questo non sarebbe quello che ti aspetti logicamente.

Ancora una volta, questo è un argomento non banale in Java. Per saperne di più, esplora gli argomenti qui su SO e gli Interwebs su:

Continua ad esplorare questi argomenti fino a quando il nome "Brian Goetz" non viene associato in modo permanente al termine "concorrenza" nel tuo cervello.


71
Quindi, fondamentalmente questa parola chiave sincronizzata rende i tuoi metodi thread-safe?
Rigo Vides,

82
La parola chiave sincronizzata è uno degli strumenti che rendono sicuro il tuo thread di codice. Il solo uso della sincronizzazione su un metodo o una variabile in sé può o meno fare il trucco. Avere una conoscenza di base del modello di memoria Java è davvero importante per ottenere la concorrenza corretta.
Stu Thompson,

28
A meno che tu non sia Brian Goetz (o forse Jon Skeet), è quasi impossibile ottenere la concorrenza Java corretta solo con le lingue primitive (sincronizzate, volatili). Per cominciare, usa il pacchetto java.util.concurrent e costruisci sopra quello.
Thilo,

12
Più chiaramente: i metodi sincronizzati non possono essere richiamati contemporaneamente da più thread.
Peter - Ripristina Monica

2
@peterh sincronizzato fa di più, quindi la spiegazione più dettagliata
Stu Thompson,

294

Beh, penso che ne abbiamo abbastanza di spiegazioni teoriche, quindi considera questo codice

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n");
    }
}

public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run() {
        theDemo.test(name);
    }
}

public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0;i<10;i++) {
            SOP.print(name + " :: "+i);
            try{
                Thread.sleep(500);
            } catch (Exception e) {
                SOP.print(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo);
    }
}

Nota: synchronizedblocca la chiamata del thread successivo al metodo test () a condizione che l'esecuzione del thread precedente non sia terminata. I thread possono accedere a questo metodo uno alla volta. Senza synchronizedtutti i thread è possibile accedere a questo metodo contemporaneamente.

Quando un thread chiama il metodo sincronizzato "test" dell'oggetto (qui oggetto è un'istanza della classe "TheDemo") acquisisce il blocco di quell'oggetto, qualsiasi nuovo thread non può chiamare QUALSIASI metodo sincronizzato dello stesso oggetto fintanto che il thread precedente che aveva acquisito il blocco non rilascia il blocco.

Una cosa simile accade quando viene chiamato un metodo sincronizzato statico della classe. Il thread acquisisce il blocco associato alla classe (in questo caso qualsiasi metodo sincronizzato non statico di un'istanza di quella classe può essere chiamato da qualsiasi thread perché quel blocco a livello di oggetto è ancora disponibile). Qualsiasi altro thread non sarà in grado di chiamare alcun metodo sincronizzato statico della classe fintanto che il blocco a livello di classe non viene rilasciato dal thread che attualmente detiene il blocco.

Uscita sincronizzata

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9

Uscita senza sincronizzazione

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9

7
Grande esempio, è bene conoscere la teoria, ma il codice è sempre più specifico e completo.
Santi Iglesias,

2
@SantiIglesias "Complete"? No. Questo esempio dimostra il comportamento di blocco di synchronized, ma la coerenza della memoria viene ignorata.
Stu Thompson,

2
La coerenza della memoria di @Stu Thompson è il risultato del blocco
Dheeraj Sachan,

@DheerajSachan In base a tale logica, l'utilizzo di ReentrantLock determinerebbe la coerenza della memoria. Non
Stu Thompson,

3
@boltup_im_coding: il metodo start () mette il Thread in uno stato "RUNNABLE", il che significa che è pronto per l'esecuzione o già in esecuzione. Può succedere che un altro thread (di solito ma non necessariamente con priorità più alta) nello stato Runnable salti la coda e inizi l'esecuzione. Nell'esempio sopra, THREAD 3 è riuscito a ottenere la CPU prima di THREAD 2.
Sahil J

116

La synchronizedparola chiave impedisce l'accesso simultaneo a un blocco di codice o oggetto da parte di più thread. Tutti i metodi Hashtablesono synchronized, quindi solo un thread può eseguirne uno alla volta.

Quando si utilizzano non -build synchronizedcome HashMap, è necessario creare funzioni di sicurezza del thread nel codice per evitare errori di coerenza.


81

synchronizedsignifica che in un ambiente multi-thread, un oggetto con synchronizedmetodo / i / blocchi / i non consente a due thread di accedere contemporaneamente ai synchronizedmetodi / blocchi / i di codice. Ciò significa che un thread non può leggere mentre un altro thread lo aggiorna.

Il secondo thread invece attenderà fino a quando il primo thread non avrà completato la sua esecuzione. Il sovraccarico è la velocità, ma il vantaggio è la coerenza garantita dei dati.

Se l'applicazione è a thread singolo, i synchronizedblocchi non offrono vantaggi.


54

La synchronizedparola chiave fa sì che un thread ottenga un blocco quando si inserisce il metodo, in modo che solo un thread possa eseguire il metodo contemporaneamente (per la specifica istanza di oggetto, a meno che non sia un metodo statico).

Questo è spesso chiamato rendere la classe thread-safe, ma direi che si tratta di un eufemismo. Mentre è vero che la sincronizzazione protegge lo stato interno del Vector dalla corruzione, ciò di solito non aiuta molto l'utente di Vector.

Considera questo:

 if (vector.isEmpty()){
     vector.add(data);
 }

Anche se i metodi coinvolti sono sincronizzati, poiché vengono bloccati e sbloccati singolarmente, due thread purtroppo temporizzati possono creare un vettore con due elementi.

Quindi, in effetti, è necessario sincronizzare anche il codice dell'applicazione.

Poiché la sincronizzazione a livello di metodo è a) costosa quando non è necessaria eb) insufficiente quando è necessaria la sincronizzazione, ora ci sono sostituzioni non sincronizzate (ArrayList nel caso di Vector).

Più recentemente, il pacchetto di concorrenza è stato rilasciato, con una serie di utility intelligenti che si occupano di problemi multi-threading.


27

Panoramica

La parola chiave sincronizzata in Java ha a che fare con la sicurezza dei thread, ovvero quando più thread leggono o scrivono la stessa variabile.
Ciò può avvenire direttamente (accedendo alla stessa variabile) o indirettamente (utilizzando una classe che utilizza un'altra classe che accede alla stessa variabile).

La parola chiave sincronizzata viene utilizzata per definire un blocco di codice in cui più thread possono accedere alla stessa variabile in modo sicuro.

Più profondo

Per quanto riguarda la sintassi, la synchronizedparola chiave accetta un Objectcome parametro (chiamato oggetto di blocco ), seguito da un { block of code }.

  • Quando l'esecuzione rileva questa parola chiave, il thread corrente tenta di "bloccare / acquisire / possedere" (scegli) l' oggetto lock ed eseguire il blocco di codice associato dopo che il blocco è stato acquisito.

  • Qualsiasi scrittura su variabili all'interno del blocco di codice sincronizzato è garantita per essere visibile a tutti gli altri thread che eseguono allo stesso modo il codice all'interno di un blocco di codice sincronizzato utilizzando lo stesso oggetto di blocco .

  • Solo un thread alla volta può contenere il blocco, durante il quale tutti gli altri thread che tentano di acquisire lo stesso oggetto di blocco aspetteranno (sospenderne l'esecuzione). Il blocco verrà rilasciato quando l'esecuzione esce dal blocco di codice sincronizzato.

Metodi sincronizzati:

Aggiunta di synchronizedparola chiave per una definizione di metodo è uguale al corpo intero procedimento essendo avvolto in un blocco di codice sincronizzato con l' oggetto di blocco essendo this (per metodi di istanza) e ClassInQuestion.getClass() (per metodi di classe) .

- Il metodo di istanza è un metodo che non ha staticparole chiave.
- Il metodo di classe è un metodo che ha una staticparola chiave.

Tecnico

Senza sincronizzazione, non è garantito in quale ordine avvengano le letture e le scritture, lasciando possibilmente la variabile con immondizia.
(Ad esempio una variabile potrebbe finire con la metà dei bit scritti da un thread e la metà dei bit scritti da un altro thread, lasciando la variabile in uno stato che nessuno dei thread ha provato a scrivere, ma un pasticcio combinato di entrambi.)

Non è sufficiente completare un'operazione di scrittura in un thread prima (tempo di clock) un altro thread lo legge, poiché l'hardware potrebbe aver memorizzato nella cache il valore della variabile e il thread di lettura vedrebbe il valore memorizzato nella cache invece di quello su cui è stato scritto esso.

Conclusione

Pertanto, nel caso di Java, è necessario seguire il modello di memoria Java per assicurarsi che non si verifichino errori di threading.
In altre parole: usa la sincronizzazione, le operazioni atomiche o le classi che le usano per te sotto i cofani.

fonti

http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Specifiche del linguaggio Java®, 2015-02-13


Scusate, ma ho questo esempio e non capisco il significato: `Integer i1 = Arrays.asList (1,2,3,4,5) .stream (). FindAny (). Get (); synchronized (i1) {Integer i2 = Arrays.asList (6,7,8,9,10) .parallelStream () .sorted () .findAny (). get (); System.out.println (i1 + "" + i2); } `1. Perché hai invocato il blocco nella prima istanza e questa invocazione non ha alcun effetto sul codice? 2. La seconda istanza sarà thread-safe, nonostante l'invocazione del blocco sulla prima?
Adryr83,

1
@ Adryr83 Se hai una domanda, puoi probabilmente farla pubblicando una nuova domanda. Ma dal momento che siamo qui, analizzerò ciò che posso (la tua domanda è un po 'difficile da capire). Da quello che posso dire su quel pezzo di codice, non sembra contenere nulla che richieda la sincronizzazione. È fuori contesto. Suggerimento: se puoi, prova a dividere il codice in singoli pezzi più piccoli, quindi cerca le risposte su questi. È molto più semplice cercare di capire problemi piccoli e isolati, piuttosto che cercare di capire un grosso blocco di codice.
Gima,

21

Pensalo come una specie di tornello come potresti trovare in un campo da calcio. Ci sono flussi paralleli di persone che vogliono entrare, ma al tornello sono "sincronizzati". Solo una persona alla volta può passare. Tutti quelli che vogliono superare lo faranno, ma potrebbero dover aspettare fino a quando non riescono a passare.


16

Qual è la parola chiave sincronizzata?

I thread comunicano principalmente condividendo l'accesso ai campi e gli oggetti a cui fanno riferimento i campi di riferimento. Questa forma di comunicazione è estremamente efficiente, ma rende possibili due tipi di errori: interferenza di thread ed errori di coerenza della memoria . Lo strumento necessario per prevenire questi errori è la sincronizzazione.

Blocchi o metodi sincronizzati impediscono l'interferenza del thread e assicurano che i dati siano coerenti. In qualsiasi momento, solo un thread può accedere a un blocco o metodo sincronizzato ( sezione critica ) acquisendo un blocco. Altri thread attenderanno il rilascio del blocco per accedere alla sezione critica .

Quando vengono sincronizzati i metodi?

I metodi vengono sincronizzati quando si aggiunge la synchronizeddefinizione o la dichiarazione del metodo. Puoi anche sincronizzare un particolare blocco di codice con un metodo.

Cosa significa pro grammaticalmente e logicamente?

Significa che solo un thread può accedere alla sezione critica acquisendo un blocco. A meno che questo thread non rilasci questo lock, tutti gli altri thread dovranno attendere per acquisire un lock. Non hanno accesso per accedere alla sezione critica senza blocco acquisizione.

Questo non può essere fatto con una magia. È responsabilità del programmatore identificare le sezioni critiche nell'applicazione e proteggerle di conseguenza. Java fornisce un framework per proteggere l'applicazione, ma dove e cosa tutte le sezioni da proteggere sono responsabilità del programmatore.

Maggiori dettagli dalla pagina della documentazione di Java

Blocchi intrinseci e sincronizzazione:

La sincronizzazione si basa su un'entità interna nota come blocco intrinseco o blocco monitor. I blocchi intrinseci svolgono un ruolo in entrambi gli aspetti della sincronizzazione: imporre l'accesso esclusivo allo stato di un oggetto e stabilire relazioni che accadono prima che siano essenziali per la visibilità.

A ogni oggetto è associato un blocco intrinseco . Per convenzione, un thread che necessita di un accesso esclusivo e coerente ai campi di un oggetto deve acquisire il blocco intrinseco dell'oggetto prima di accedervi, quindi rilasciare il blocco intrinseco una volta terminato con essi.

Si dice che un thread possiede il blocco intrinseco tra il momento in cui ha acquisito il blocco e rilasciato il blocco. Finché un thread possiede un blocco intrinseco, nessun altro thread può acquisire lo stesso blocco. L'altro thread si bloccherà quando tenta di acquisire il blocco.

Quando un thread rilascia un blocco intrinseco, viene stabilita una relazione che precede tra quell'azione e qualsiasi successiva acquisizione dello stesso blocco.

Rendere sincronizzati i metodi ha due effetti :

In primo luogo, non è possibile interlacciare due invocazioni di metodi sincronizzati sullo stesso oggetto.

Quando un thread esegue un metodo sincronizzato per un oggetto, tutti gli altri thread che invocano metodi sincronizzati per lo stesso blocco di oggetti (sospensione dell'esecuzione) fino a quando il primo thread non viene eseguito con l'oggetto.

In secondo luogo, quando esce un metodo sincronizzato, stabilisce automaticamente una relazione prima dell'evocazione successiva di un metodo sincronizzato per lo stesso oggetto.

Ciò garantisce che le modifiche allo stato dell'oggetto siano visibili a tutti i thread.

Cerca altre alternative alla sincronizzazione in:

Evitare sincronizzato (questo) in Java?


11

Synchronized normal methodequivalente a Synchronized statement(utilizzare questo)

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

Synchronized static methodequivalente a Synchronized statement(classe d'uso)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

Istruzione sincronizzata (usando la variabile)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

Per synchronized, abbiamo entrambi Synchronized Methodse Synchronized Statements. Tuttavia, Synchronized Methodsè simile a quello che Synchronized Statementsdobbiamo solo capire Synchronized Statements.

=> Fondamentalmente, avremo

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

Ecco 2 pensa che aiutano a capire synchronized

  • Ogni oggetto / classe ha un intrinsic lockassociato con esso.
  • Quando un thread richiama a synchronized statement, acquisisce automaticamente l' oggetto intrinsic lockper synchronized statement'squell'oggetto e lo rilascia quando il metodo ritorna. Finché un thread possiede un thread intrinsic lock, NESSUN altro thread può acquisire il SAME lock => thread safe.

=> Quando un thread Ainvoke synchronized(this){// code 1}=> tutto il codice di blocco (all'interno della classe) dove have synchronized(this)e all synchronized normal method(all'interno della classe) è bloccato perché SAME lock. Verrà eseguito dopo lo thread Asblocco ("// code 1" terminato).

Questo comportamento è simile a synchronized(a variable){// code 1}o synchronized(class).

SAME LOCK => lock (non dipende da quale metodo? O quali istruzioni?)

Utilizzare il metodo sincronizzato o le istruzioni sincronizzate?

Preferisco synchronized statementsperché è più allungabile. Esempio, in futuro, devi solo sincronizzare una parte del metodo. Esempio, hai 2 metodi sincronizzati e non sono rilevanti l'uno per l'altro, tuttavia quando un thread esegue un metodo, bloccherà l'altro metodo (può impedirlo con l'uso synchronized(a variable)).

Tuttavia, applicare il metodo sincronizzato è semplice e il codice sembra semplice. Per alcune classi, esiste solo 1 metodo sincronizzato o tutti i metodi sincronizzati nella classe in relazione reciproca => che possiamo usare synchronized methodper rendere il codice più breve e facile da capire

Nota

(non è rilevante per molto synchronized, è la differenza tra oggetto e classe o nessuna-statica e statica).

  • Quando si utilizza synchronizedil metodo normale o synchronized(this)oppure synchronized(non-static variable)si sincronizzerà sulla base di ogni istanza di oggetto.
  • Quando si utilizza synchronizedun metodo statico synchronized(class)o synchronized(static variable)si sincronizzerà in base alla classe

Riferimento

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Spero che sia d'aiuto


11

Ecco una spiegazione da The Java Tutorials .

Considera il seguente codice:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

if countè un'istanza di SynchronizedCounter, quindi rendere sincronizzati questi metodi ha due effetti:

  • In primo luogo, non è possibile interlacciare due invocazioni di metodi sincronizzati sullo stesso oggetto. Quando un thread esegue un metodo sincronizzato per un oggetto, tutti gli altri thread che invocano metodi sincronizzati per lo stesso blocco di oggetti (sospensione dell'esecuzione) fino a quando il primo thread non viene eseguito con l'oggetto.
  • In secondo luogo, quando esce un metodo sincronizzato, stabilisce automaticamente una relazione prima dell'evocazione successiva di un metodo sincronizzato per lo stesso oggetto. Ciò garantisce che le modifiche allo stato dell'oggetto siano visibili a tutti i thread.

9

Per la mia comprensione sincronizzato significa sostanzialmente che il compilatore scrive monitor.enter e monitor.exit attorno al tuo metodo. In quanto tale, può essere thread-safe a seconda di come viene utilizzato (ciò che intendo è che puoi scrivere un oggetto con metodi sincronizzati che non è thread-safe a seconda di ciò che fa la tua classe).


5

Quello che manca alle altre risposte è un aspetto importante: le barriere della memoria . La sincronizzazione dei thread è essenzialmente composta da due parti: serializzazione e visibilità. Consiglio a tutti di google di "jvm memory barrier", in quanto si tratta di un argomento non banale ed estremamente importante (se si modificano i dati condivisi a cui accedono più thread). Dopo averlo fatto, consiglio di guardare le classi del pacchetto java.util.concurrent che aiutano a evitare l'uso della sincronizzazione esplicita, che a sua volta aiuta a mantenere i programmi semplici ed efficienti, forse anche a prevenire i deadlock.

Uno di questi esempi è ConcurrentLinkedDeque . Insieme al modello di comando consente di creare thread di lavoro altamente efficienti inserendo i comandi nella coda simultanea: nessuna sincronizzazione esplicita necessaria, nessun deadlock possibile, nessun sonno esplicito () necessario, basta eseguire il polling della coda chiamando take ().

In breve: si verifica la "sincronizzazione della memoria" implicitamente quando si avvia un thread, un thread termina, si legge una variabile volatile, si sblocca un monitor (si lascia un blocco / funzione sincronizzato) ecc. Questa "sincronizzazione" influisce (in un certo senso "arrossisce ") tutte le scritture fatte prima di quella particolare azione. Nel caso del summenzionato ConcurrentLinkedDeque , la documentazione "dice":

Effetti di coerenza della memoria: come con altre raccolte simultanee, le azioni in un thread prima di posizionare un oggetto in un ConcurrentLinkedDeque avvengono prima delle azioni successive all'accesso o alla rimozione di quell'elemento dal ConcurrentLinkedDeque in un altro thread.

Questo comportamento implicito è un aspetto un po 'pernicioso perché la maggior parte dei programmatori Java senza molta esperienza prenderà molto come dato a causa di esso. E poi improvvisamente inciampare su questo thread dopo che Java non sta facendo quello che dovrebbe "fare" in produzione dove c'è un carico di lavoro diverso - ed è piuttosto difficile testare i problemi di concorrenza.


3

Sincronizzato significa semplicemente che più thread se associati a un singolo oggetto possono impedire la lettura e la scrittura sporche se si utilizza un blocco sincronizzato su un oggetto particolare. Per darti maggiore chiarezza, facciamo un esempio:

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

Abbiamo creato due oggetti classe MyRunnable, runnable1 condiviso con thread 1 e thread 3 e runnable2 condiviso solo con thread 2. Ora, quando t1 e t3 si avviano senza l'uso della sincronizzazione, l'output PFB suggerisce che entrambi i thread 1 e 3 influenzano simultaneamente il valore var dove per il thread 2, var ha la propria memoria.

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

Utilizzando Synchronzied, thread 3 in attesa del completamento del thread 1 in tutti gli scenari. Sono stati acquisiti due blocchi, uno su runnable1 condiviso dal thread 1 e thread 3 e l'altro su runnable2 condiviso solo dal thread 2.

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18

Sincronizzato significa anche di più: ha un impatto profondo sulla barriera della memoria.
user1050755

1

sincronizzato semplice significa che due thread non possono accedere contemporaneamente al blocco / metodo. Quando diciamo che qualsiasi blocco / metodo di una classe è sincronizzato significa che solo un thread alla volta può accedervi. Internamente il thread che tenta di accedervi per primo prende un lock su quell'oggetto e fintanto che questo lock non è disponibile nessun altro thread può accedere a nessuno dei metodi / blocchi sincronizzati di quell'istanza della classe.

Nota un altro thread può accedere a un metodo dello stesso oggetto che non è definito come sincronizzato. Un thread può rilasciare il blocco chiamando

Object.wait()

0

synchronizedblocco in Java è un monitor in multithreading. synchronizedil blocco con lo stesso oggetto / classe può essere eseguito da un solo thread, tutti gli altri sono in attesa. Può essere d'aiuto in race conditionsituazioni in cui diversi thread tentano di aggiornare la stessa variabile (il primo passo utilizza volatileInformazioni )

Java 5esteso synchronizedsupportando happens-before[Informazioni]

Si verifica uno sblocco (blocco sincronizzato o uscita del metodo) di un monitor prima di ogni blocco successivo (blocco sincronizzato o immissione del metodo) dello stesso monitor.

Il prossimo passo è java.util.concurrent

volatile vs sincronizzato


-6

Sincronizzato è una parola chiave in Java che viene utilizzata per far accadere prima della relazione in ambiente multithreading per evitare incoerenze di memoria ed errori di interferenza del thread.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.