2015-10-06 8 views
5

La variabile emitting può essere volatile? il metodo emit() viene chiamato da diversi thread ed emette deve essere visibile.
Ma è accessibile solo nei blocchi synchronized. Gli // ... sono posti in cui il lavoro è terminato, ma in questo caso non viene fatto riferimento a emitting.È volatile necessario, in caso di accesso solo sincronizzato

Quindi, se la struttura di synchronized è risolvibile, ho ancora bisogno di un volatile per emitting o no? (E perché?)

static final class C { 
    boolean emitting = false; // shall be volatile ? 

    public void emit() { 
     synchronized (this) { 
      if (emitting) { 
       return; 
      } 
      // ... 
      emitting = true; 
     } 

     // ... 

     synchronized (this) { 
      if (!condition()) { 
       emitting = false; 
       return; 
      } 
     } 
     // ... 
    } 

Frank

risposta

5

Se vi si accede solo dal synchronized blocchi non è necessaria la parola chiave volatile.

Sincronizzato garantisce che le modifiche alle variabili accessibili all'interno del blocco sincronizzato siano visibili a tutti i thread che entrano in un blocco sincronizzato.

Dal libro Java concorrenza in pratica:

Per pubblicare un oggetto sicurezza, sia il riferimento all'oggetto e lo stato dell'oggetto deve essere reso visibile ad altri thread allo stesso tempo. Un oggetto correttamente costruito può essere tranquillamente pubblicato da:

  • Inizializzazione di un riferimento oggetto da un inizializzatore statico;
  • Memorizzazione di un riferimento ad esso in un campo volatile o riferimento atomico ;
  • Memorizzazione di un riferimento ad esso in un campo finale di un oggetto costruito correttamente;
  • Memorizzazione di un riferimento ad esso in un campo che è correttamente protetto da un blocco.

Nota:sorvegliata da un blocco significa inserito in un blocco sincronizzato