34

Qual è la differenza tra un metodo sincronizzato e un blocco sincronizzato in Java?Qual è la differenza tra un metodo sincronizzato e un blocco sincronizzato in Java?

Ho cercato la risposta in rete, le persone sembrano essere così sicuri di questo :-(

La mia opinione sarebbe non v'è alcuna differenza tra i due, solo che il blocco di sincronizzazione potrebbe essere più localizzato nella portata e, quindi, il blocco sarà di minor tempo ??

e in caso di blocco su un metodo statico, su ciò che è preso il blocco? Qual è il significato di un blocco su di classe?

+0

@ try-catch-, infine, che non è un duplicato di questo problema; quella domanda chiede se un metodo sincronizzato fornisce accesso esclusivo al solo metodo o all'intero oggetto. –

+0

@MarkRotteveel Hai ragione in termini di diversi titoli. D'altra parte, le risposte dell'altro interrogativo coprono anche le differenze: esaminare la sezione sincronizzata con alcune affermazioni (o meno) e controllare dove bloccare (o non avere alcun controllo su ciò). –

risposta

44

Un metodo sincronizzato utilizza il ricevitore del metodo come blocco (ad es. this per i metodi non statici e la classe di inclusione per i metodi statici). I blocchi Synchronized utilizzano l'espressione come blocco.

Così i due metodi seguenti sono equivalenti bloccaggio prospettico:

synchronized void mymethod() { ... } 

void mymethod() { 
    synchronized (this) { ... } 
} 

Per i metodi statici, la classe sarà chiuso:

class MyClass { 
    synchronized static mystatic() { ... } 

    static mystaticeq() { 
    syncrhonized (MyClass.class) { ... } 
    } 
} 

Per blocchi sincronizzati, è possibile utilizzare qualsiasi non null oggetto come blocco:

synchronized (mymap) { 
    mymap.put(..., ...); 
} 

Blocco ambito

Per i metodi sincronizzati, il blocco verrà mantenuto nell'intero ambito del metodo, mentre nel blocco synchronized, il blocco viene mantenuto solo durante lo scope del blocco (altrimenti noto come sezione critica). In pratica, la JVM può ottimizzare rimuovendo alcune operazioni dall'esecuzione del blocco synchronized se può dimostrare che può essere eseguita in modo sicuro.

+0

Ho letto qualche tempo fa (perso l'origine) che sincronizzato sul metodo può essere più semplice da ottimizzare internamente da JVM che sincronizzato su blocco anche se quel blocco incapsula l'intero corpo del metodo. Potrebbe essere interessante micro-benchmark da provare. –

+1

Nell'ambito del blocco, probabilmente intendevi "... mentre nel blocco sincronizzato, il blocco viene mantenuto solo durante il blocco sincronizzato" e non "... mentre nel metodo sincronizzato il blocco viene mantenuto solo durante il blocco sincronizzato" – mrvincenzo

+2

@Gregory Mostizky In base a questo articolo, JVM crea meno bytecode per un metodo sincronizzato rispetto a un blocco sincronizzato. http://www.ibm.com/developerworks/java/library/j-5things15/index.html?ca=drs- –

3

Sì , questa è una differenza, l'altra è che puoi acquisire un blocco su altri oggetti rispetto a this.

8

Un metodo sincronizzato è una scorciatoia. Questo:

class Something { 
    public synchronized void doSomething() { 
     ... 
    } 

    public static synchronized void doSomethingStatic() { 
     ... 
    } 
} 

è, per tutti gli effetti, equivalente a questo:

class Something { 
    public void doSomething() { 
     synchronized(this) { 
      ... 
     } 
    } 

    public static void doSomethingStatic() { 
     synchronized(Something.class) { 
      ... 
     } 
    } 
} 

(. Dove Something.class è l'oggetto di classe per la classe Something)

Così in effetti, con un blocco sincronizzato, puoi essere più specifico sul tuo lucchetto, e più a grana fine quando vuoi usarlo, ma a parte questo non c'è differenza.

0

Procedimento sincronizzati serrature sulla istanza di oggetto il procedimento viene contenuta in

Dove come un blocco sincronizzato può bloccare su qualsiasi oggetto -. Tipicamente un obect mutex definita come una variabile di istanza. Ciò consente un maggiore controllo su quali blocchi sono in funzione.

2

La differenza chiave è la seguente: se si dichiara un metodo per la sincronizzazione, l'intero corpo del metodo diventa sincronizzato; se si utilizza il blocco sincronizzato, tuttavia, è possibile circondare solo la "sezione critica" del metodo nel blocco sincronizzato, lasciando il resto del metodo fuori dal blocco.

Se l'intero metodo fa parte della sezione critica, allora non c'è alcuna differenza. Se questo non è il caso, dovresti usare un blocco sincronizzato attorno alla sezione critica. Più affermazioni hai in un blocco sincronizzato, minore è il parallelismo generale che ottieni, quindi vuoi mantenerle al minimo.

+0

Follow-up rapido: significherebbe che un blocco sincronizzato è meno costoso da utilizzare rispetto a un metodo sincronizzato ? – Everyone

+0

Se il blocco sincronizzato include tutti i contenuti della funzione, non vi sono differenze. Tuttavia, se si utilizza un blocco sincronizzato, è possibile circondare solo la sezione critica (magari lasciando un po 'del calcolo fuori dalla regione sincronizzata). Se lo fai, il tuo programma funzionerà più velocemente. –

0

Il mio take sarebbe non c'è alcuna differenza tra i due, tranne che il blocco di sincronizzazione potrebbe essere più localizzato in ambito e quindi il blocco sarà di minor tempo ??

Sì. Hai ragione. A differenza dei metodi synchronized, le istruzioni sincronizzate devono specificare l'oggetto che fornisce il blocco intrinseco.

Esempio da java tutorial:

public void addName(String name) { 
    synchronized(this) { 
     lastName = name; 
     nameCount++; 
    } 
    nameList.add(name); 
} 

dichiarazioni sincrone sono anche utili per migliorare la concorrenza con sincronizzazione a grana fine. Puoi trovare un buon esempio nella stessa pagina di esercitazione per il caso d'uso successivo.

Supponiamo, ad esempio, che la classe MsLunch abbia due campi di istanza, c1 e c2, che non vengono mai utilizzati insieme. Tutti gli aggiornamenti di questi campi devono essere synchronized, ma non c'è motivo di impedire che un aggiornamento di c1 venga intercalato con un aggiornamento di c2 e così facendo si riduce la concorrenza creando blocchi non necessari. Invece di utilizzare metodi sincronizzati o utilizzare in altro modo il blocco associato a questo, creiamo due oggetti esclusivamente per fornire i blocchi.

E in caso di blocco su un metodo statico, su quale è la serratura presa? Qual è il significato di un Lock on Class?

In questo caso, il thread acquisisce il blocco intrinseco per l'oggetto Classe associato alla classe. Pertanto l'accesso ai campi statici della classe è controllato da un blocco che è diverso dal blocco per qualsiasi istanza della classe.

Quando si effettua un metodo come synchronized (non static):

Non è possibile che due invocazioni di synchronized metodi sullo stesso oggetto per Interleave. Quando un thread sta eseguendo un metodo sincronizzato per un oggetto, tutti gli altri thread che invocano metodi sincronizzati per lo stesso blocco oggetto (sospendi l'esecuzione) finché il primo thread non viene eseguito con l'oggetto.

Se si effettua un metodo come static synchronized:

Non è possibile che due invocazioni di static synchronized metodi su diversi oggetti della stessa classe per Interleave. Quando un thread sta eseguendo un metodo static synchronized per un oggetto di Classe A, tutti gli altri thread che invocano i metodi static synchronized su qualsiasi oggetto del blocco di Classe A (sospendi l'esecuzione) finché il primo thread non viene eseguito con l'esecuzione del metodo.

a trovare migliori alternative a sincronizzazione in questa domanda SE:

Avoid synchronized(this) in Java?

Problemi correlati