2012-06-25 13 views
10

Ho un dubbio sulla sincronizzazione Java. Voglio sapere se ho tre metodi sincronizzati nella mia classe e un thread acquisisce il blocco in un metodo sincronizzato, altri due saranno bloccati? Sto facendo questa domanda perché sono confuso dalla seguente affermazione.Come funziona la sincronizzazione in Java?

Mentre un thread è all'interno di un metodo sincronizzato di un oggetto, tutti gli altri thread che desiderano eseguire questo metodo sincronizzato o qualsiasi altro metodo sincronizzato dell'oggetto devono attendere. Questa restrizione non si applica al thread che ha già il blocco e sta eseguendo un metodo sincronizzato dell'oggetto. Un tale metodo può richiamare altri metodi sincronizzati dell'oggetto senza essere bloccato. I metodi non sincronizzati dell'oggetto possono naturalmente essere richiamati in qualsiasi momento da qualsiasi thread

+1

Qual è la fonte di questa affermazione e qual è la tua confusione? Sembri capirlo. Prestare attenzione al deadlock quando si accede a un metodo sincronizzato da un altro. – Sridhar

+0

Ri: "... gli altri due saranno bloccati". Il thread attualmente in esecuzione che ha già il lock non verrà impedito dal chiamare un altro metodo sincronizzato sullo stesso oggetto, tuttavia qualsiasi altro thread verrà bloccato (cioè forzato ad aspettare fino a che non viene dato il lock). Max ha una buona risposta che parla se stai bloccando l'oggetto stesso (cioè questo) o un'altra variabile oggetto interamente. – Brad

risposta

7

La sincronizzazione in java viene eseguita tramite l'acquisizione del monitor su un oggetto specifico. Pertanto, se si fa questo:

class TestClass { 
    SomeClass someVariable; 

    public void myMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 

    public void myOtherMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 
} 

Poi quelle due blocchi saranno protetti da esecuzione di 2 fili diversi in qualsiasi momento mentre someVariable non viene modificato. Fondamentalmente, si dice che quei due blocchi siano sincronizzati rispetto alla variabile someVariable.

Quando si inserisce synchronized nel metodo, in pratica significa lo stesso di synchronized (this), ovvero una sincronizzazione sull'oggetto su cui viene eseguito questo metodo.

Cioè:

public synchronized void myMethod() { 
    ... 
} 

Significa la stessa:

public void myMethod() { 
    synchronized (this) { 
     ... 
    } 
} 

Quindi, per rispondere alla tua domanda - sì, le discussioni non saranno in grado di chiamare simultaneamente quei metodi in diversi thread, poiché entrambi hanno un riferimento allo stesso monitor, il monitor dell'oggetto this.

+0

Max, il termine "blocco" nella tua ultima frase è fuorviante. Penso che volevi dire "... dato che entrambi hanno un riferimento allo stesso monitor". Due thread non possono contenere un blocco dallo stesso monitor allo stesso tempo. – Brad

+0

@Brad Grazie per la correzione, aggiornato. – bezmax

+0

Non ottenendo ciò che hai comunicato nel primo paragrafo, puoi spiegarlo in termini più semplici. – userab

1

Sì.
Per eseguire il thread del metodo sincronizzato è necessario ottenere il blocco sull'oggetto e solo un thread alla volta può ottenere il blocco sull'oggetto.

0

Ogni oggetto java (istanza di classe) ha un oggetto mutex. La parola chiave sincronizzata di fronte a un metodo indica che il thread in esecuzione deve ottenere il blocco sul mutex per quell'oggetto. In realtà,

public synchronized doSomething(){ 
    ... 
} 

è esattamente lo stesso di questo:

public doSomething(){ 
    synchronized(this){ 
     ... 
    } 
} 

Quindi sì, ci sarà solo un thread l'esecuzione di un metodo sincronizzato per istanza di classe.

Si noti che a volte questo può non essere ottimale, dal momento che si desidera proteggere le modifiche, ma sta bene con concomitante legge, nel qual caso, anziché la parola chiave sincronizzato, si potrebbe voler esaminare ReadWriteLock.

-1

Non sono sicuro di ciò che si trova confuso, ma l'acquisizione di un blocco blocca altri thread dall'acquisirlo mentre lo si tiene e tutti i metodi sincronizzati non statici di una classe si sincronizzano sullo stesso oggetto, quindi la risposta alla tua domanda è "sì", supponendo di aver capito bene. Non so cos'altro significherebbe "sincronizzato", o quale sarebbe il suo uso con qualsiasi altro significato.

0

beh, c'è solo un blocco per oggetto. e tutti i metodi sincronizzati sono bloccati da questo blocco. Quindi, qualsiasi thread acquisisca il blocco alla volta, è autorizzato a passare attraverso tutti i metodi sincronizzati. Ma i thread che attendono il lock non possono entrare in metodi di sincronizzazione finché non ottengono il lock.

Quindi in un momento solo le regole del thread e altre devono attendere per immettere qualsiasi metodo sincronizzato, non importa che il thread dominante esegua quel metodo o meno.

0

Sì, tutti i thread tranne quello che ha acquisito il blocco dovranno attendere il rilascio del blocco per poter eseguire uno dei tre metodi sincronizzati.

Ricordate, un metodo sincronizzato è lo stesso di un normale metodo circondato da

synchronized(this) { 
    // method body 
} 
0

È vero e lo fa in questo modo. È inoltre necessario uniformare i dati di quell'oggetto.

Supponiamo che questa convalida non sia presente e che sia presente una variabile x che viene manipolata da 2 diversi metodi sincronizzati xxx() e yyy().

quindi se il thread A ottiene il blocco del metodo xxx() che sta manipolando x = 5 e il secondo thread B ottiene il blocco del metodo yyy() e manipolando x = -5 così alla fine del metodo xxx() il thread A è aspettando x = 5 ma otterrà x = 0 che è sbagliato.

Ecco perché è implementato in questo modo.

0

Se una classe ha 4 metodi di sincronizzazione, allora sì alla volta solo un thread avrà accesso a questi metodi. Suppongo che il dubbio fosse, ogni thread può accedere a metodi sincronizzati alla volta per istanza di classe singola. La risposta è no. Solo un thread può accedere ai metodi sincronizzati alla volta.

Problemi correlati