Se accedo ad un oggetto all'interno di un metodo sincronizzato o di un blocco sincronizzato, anche tutti gli oggetti in quell'elemento a cui si accede sono sincronizzati?La sincronizzazione di Java aggiornerà la cache completa o solo l'oggetto su cui è stato sincronizzato?
Immaginate c'è un oggetto avente un metodo Queue
add()
e take()
sincronizzato, accettando e distribuendo l'oggetto complesso Thing
. Thing
contiene molte liste con altri oggetti diversi.
Ora la filettatura di immagine Before
crea Thing
e inserisce alcuni oggetti esistenti in Thing
, modifica alcuni di questi oggetti e così via. Il thread Before
aggiunge Thing
a Queue
. Un po 'più tardi thread After
prende il Thing
da Queue
.
DOMANDA: Sarà Thing
e tutti i suoi figli/subobject essere nello stesso stato di Before
lasciato in? Anche se il thread After
stava forse lavorando su uno di questi sottoelementi un po 'prima? Poiché io immagino che il processore per il thread After
abbia ancora alcune informazioni memorizzate nella cache su tale sottoelemento (l'indirizzo di quel suboggetti è sempre lo stesso). Tutto questo materiale memorizzato nella cache sarebbe invalidato solo attraverso l'accesso all'oggetto padre Thing
in modo sincronizzato?
Si prega di non dare risposte come utilizzare le librerie di concorrenza ecc. Voglio capire cosa sta succedendo.
sì lo so, ma non era proprio la mia domanda :-) La sincronizzazione deve anche influenzare le cache del processore, in modo che le modifiche vengano scaricate nella memoria comune, questo è ciò di cui si tratta la mia domanda. So che se si accede a un riferimento senza passare da un blocco sincronizzato a più thread paralleli, tutto diventa incasinato. Ma si tratta di passare più cose da un thread all'altro e assicurarsi che il datastrucuture sia ancora corretto. Capisci cosa intendo? –
Vedere la risposta di Paulo. Il blocco dei thread è solo un aspetto della sincronizzazione, la relazione di happen-before (svuotamento della cache) è importante se non di più. È anche molto più complicato da comprendere e le API non sono chiare su quanto accade prima (ad esempio, penso che SwingUtilities.invokeLater provochi un successo prima, ma non ne sono sicuro al 100%). Consiglio vivamente la Concurrency Java in Practice di Goetz et al. Mettono molta enfasi su ciò che accade prima. – toto2
Grazie per il downvoting senza spiegazione ... @Franz: Non mi era chiaro che stavi chiedendo del modello di memoria. Permettetemi di riconsiderare la mia risposta. – musiKk