- Qualcuno può spiegare la sicurezza di inizializzazione come richiesto dal modello di memoria Java?
- In che modo i campi final aiutano a raggiungere la sicurezza di inizializzazione ?
- Che ruolo ha il costruttore nell'assicurazione della sicurezza di inizializzazione ?
risposta
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. 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.
"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
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
@axtavt è impedito effettivamente il riordino rendendo un campo volatile non definitivo. Quindi il punto 2 non è corretto secondo me. – Inquisitive
+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