Domanda

È menzionato nel modello di memoria Java che: quando un thread esce da un blocco sincronizzato come parte del rilascio del monitor associato, JMM richiede che la cache del processore locale sia arrossata alla memoria principale.Allo stesso modo, come parte dell'acquisizione del monitor Quando si immette un blocco sincronizzato, le cache locali sono invalidate in modo che le letture successive passino direttamente alla memoria principale e non alla cache locale.

Allora perché in quel codice devo dichiarare un'istanza come volatile poiché quando il secondo thread entra nel blocco di sincronizzazione andrà direttamente alla memoria principale ??

public final class MySingleton {
  private static MySingleton instance = null;
  private MySingleton() { } 
  public static MySingleton getInstance() {
    if (instance == null) {
      synchronized (MySingleton.class) {
        if (instance == null) {
          instance = new MySingleton();
        }
      }
    }
    return instance;
  }
}
.

Voglio dire quando un altro thread entra in sincnica e apportare il secondo controllo che dovrebbe aggiornare dalla memoria principale come menzionato.

È stato utile?

Soluzione

La condizione di gara è questa:

    .
  1. Thread A Sees instance == NULL e sta eseguendo questo codice instance = new MySingleton();.La scrittura a instance è visibile ma le scritture in MySingleton non sono ancora.

  2. Thread B vede instance != NULL e inizia a lavorare sull'istanza.

  3. Thread B ora funziona su un oggetto la cui costruzione non può vedere.

  4. La creazione di instance volatile risolve il problema come specifica della memoria JDK, a partire da JDK5, garantisce che le scritture a oggetti non volatili non saranno visualizzati per ordine rispetto a una scrittura a un oggetto volatile.Quindi qualsiasi filettatura che vede instance != NULL deve vedere l'istanza stessa.

Altri suggerimenti

Devi dichiararlo volatile altrimenti non vi è alcuna garanzia che due chiamate a GetInstance () restituiscano la stessa istanza.

Non ci sono garanzia di accedere alla memoria principale, solo un valore coerente della cache.cioè tutte le discussioni vedranno lo stesso valore.

btw: sai ovviamente è molto più complesso del necessario.Tutto ciò di cui hai bisogno è

public enum MySingleton {
     INSTANCE;
}
.

fa molto la stessa cosa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top