14
  1. Qualcuno può spiegare la sicurezza di inizializzazione come richiesto dal modello di memoria Java?
  2. In che modo i campi final aiutano a raggiungere la sicurezza di inizializzazione ?
  3. Che ruolo ha il costruttore nell'assicurazione della sicurezza di inizializzazione ?

risposta

21

La sicurezza di inizializzazione consente a un oggetto di essere visto da una filettatura esterna nel suo stato completamente costruito (inizializzato). Il prerequisito è che l'oggetto non debba essere pubblicato prematuramente, ad es. nel suo costruttore. Una volta assicurato, JMM richiede determinati comportamenti per i campi dichiarati come final. In primo luogo, tutti i final campi di oggetto sono garantito per essere visto da una filettatura esterna nel suo stato completamente inizializzato - questo non è così banale come sembra -

consideri una classe

class A{ 
    List list ; 
    A() { 
     list = Arrays.asList(some init expressions that adds 10 elements to list); 
    } 

} 

Un filo che accede al list dell'istanza di A non è garantito per impostazione predefinita di vedere 10 elementi in tale elenco. In effetti, questo thread può anche vedere list come null. Tuttavia, se list viene dichiarato final, quindi, come richiesto da JMM, lo list deve essere sempre inizializzato con 10 elementi.

In secondo luogo, questa garanzia di inizializzazione non è limitata al campo final, ma viene estesa in modo ricorsivo a tutti gli oggetti a cui si riferisce. Ad esempio, se lo list nell'esempio precedente è un elenco di list s, allora il thread esterno è garantito per vedere gli elenchi interni completamente inizializzati.

Si noti che da nessuna parte stiamo usando synchronized per ottenere questa sicurezza nella visibilità della memoria (rapporto prima-accade).

+1

+1 per aver menzionato che la sicurezza di inizializzazione non solo garantisce la sicurezza per i campi finali ma anche per gli oggetti a cui fanno riferimento i campi finali. – Inquisitive

4

1. sicurezza inizializzazione consente costruito in modo corretto oggetti immutabili da condividere salvo attraverso fili senza usare la sincronizzazione, indipendentemente anche se pubblicati utilizzando una corsa dati.

2. oggetti aventi campo finale, sicurezza inizializzazione impediscono riordino qualsiasi parte di costruzione con il carico iniziale di un riferimento a tale oggetto.

+0

"indipendentemente dal fatto che abbiano pubblicato utilizzando una corsa di dati". Questa linea non ha alcun senso. Gli oggetti non sono pubblicati utilizzando le gare di dati :-). – Inquisitive

+2

Non sono sicuro di "impedire il riordino di qualsiasi parte della costruzione". Le garanzie per i campi finali diventano effettive solo per l'inizializzazione di quei campi finali, non di altre parti della costruzione. – axtavt

+0

@axtavt è impedito effettivamente il riordino rendendo un campo volatile non definitivo. Quindi il punto 2 non è corretto secondo me. – Inquisitive