pensare alla situazione thread singolo prima:
Ogni volta che si crea un oggetto tramite new
, il suo costruttore viene chiamato, che (si spera) inizializza i campi del nuovo oggetto prima di un riferimento a questo oggetto viene restituito. Vale a dire, dal punto di vista del chiamante, questo new
è quasi come un'operazione atomica:
Prima di chiamare new
, non c'è alcun oggetto. Dopo il ritorno da new
, l'oggetto esiste completamente inizializzato.
Quindi tutto va bene.
La situazione cambia leggermente quando entrano in gioco più thread. Ma dobbiamo leggere attentamente la vostra citazione:
... è stato completamente costruito e i suoi campi completamente inizializzati.
Il punto cruciale è fully
. L'oggetto della domanda dice "prima della creazione", ma ciò che si intende qui non è prima che l'oggetto sia stato creato, ma tra la creazione dell'oggetto e l'inizializzazione. In una situazione multi-threaded, new
non può più essere considerato (pseudo-) atomico a causa di questo (il tempo scorre da sinistra a destra):
Thread1 --> create object --> initialize object --> return from `new`
^
|
| (messing with the object)
Thread2 ------------------/
Così come può Thread2 pasticciare con l'oggetto? Avrebbe bisogno di un riferimento a quell'oggetto ma poiché new
restituirà l'oggetto solo dopo che sono stati creati e inizializzati, questo dovrebbe essere impossibile, giusto?
Bene, no, c'è un modo in cui è ancora possibile, vale a dire se viene creato il thread 2 all'interno del costruttore dell'oggetto. Poi la situazione sarebbe simile a questa:
Thread1 --> create object --> create Thread2 --> initialize object --> return from `new`
| ^
| |
| | (messing with the object)
\-----/
Dal Thread2 viene creato dopo l'oggetto è stato creato (ma prima è stato completamente inizializzato), c'è già un riferimento all'oggetto che Thread2 potrebbe ottenere un in possesso di. Un modo è semplicemente se il costruttore di Thread2 prende esplicitamente un riferimento all'oggetto come parametro. Un altro modo è utilizzare una classe interna non statica dell'oggetto per il metodo run
di Thread2.
Qualsiasi cosa tu faccia prima dell'avvio di una discussione verrà letta come ti saresti aspettato.Creare il thread alla fine del costruttore (o preferibilmente avere il creatore dell'oggetto, il chiamante, avviare una discussione) –