Jeśli uzyskam dostęp do obiektu wewnątrz metody zsynchronizowanej lub bloku zsynchronizowanego, czy obiekt w tym dostępnym elemencie jest również zsynchronizowany?Czy synchronizacja Java zaktualizuje całą pamięć podręczną lub tylko obiekt, na którym się zsynchronizowałem?
Imagine jest przedmiotem Queue
o zsynchronizowany add()
i take()
metodę, przyjmowanie i przekazywanie na zewnątrz złożonego obiektu Thing
. Thing
ma wiele list z innymi różnymi obiektami.
Teraz wątek obrazu Before
tworzy Thing
i umieszcza niektóre istniejące obiekty w Thing
, modyfikuje niektóre z tych obiektów i tak dalej. Wątek Before
dodaje Thing
do Queue
. Nieco później wątek After
pobiera Thing
z Queue
.
PYTANIE: Czy Thing
i wszystkie jego dzieci/podobiekt będą w takim samym stanie, w jakim je zostawił Before
? Nawet jeśli wątek After
może pracował nad jedną z tych podelementów nieco wcześniej? Ponieważ obraz procesora dla wątku After
może nadal zawierać pewne buforowane informacje na temat tego podelementu (adres tego obiektu podrzędnego jest wciąż taki sam). Cała ta pamięć podręczna zostanie unieważniona tylko przez zsynchronizowany dostęp do obiektu ojca Thing
?
Proszę nie udzielać odpowiedzi, takich jak używanie bibliotek współbieżnych itp. Chcę zrozumieć, co się dzieje.
Tak, wiem o tym, ale to nie było do końca moje pytanie :-) Synchronizacja musi również wpływać na pamięci podręczne procesorów, więc zmiany są przepłukiwane do wspólnej pamięci, o to właśnie chodzi. Wiem, że jeśli uzyskasz dostęp do referencji bez przechodzenia przez zsynchronizowany blok z wielu równoległych wątków, wszystko zostanie skompromitowane. Ale chodzi bardziej o przekazywanie rzeczy z jednego wątku na drugi i zapewnienie, że datastrucuture jest nadal poprawny. Rozumiesz co mam na myśli? –
Zobacz odpowiedź Paula. Blokowanie wątków jest tylko jednym aspektem synchronizacji, relacja dzieje się przedtem (opróżnianie pamięci podręcznej) jest równie ważna, jeśli nie większa. Jest to również trudniejsze do zrozumienia, a API nie jest jasne o tym, co się dzieje - wcześniej (na przykład, myślę, że SwingUtilities.invokeLater prowokuje zdarzenie przed, ale nie jestem w 100% pewny). Gorąco polecam Java Concurrency in Practice od Goetz et al. Przywiązują dużą wagę do tego, co się dzieje - wcześniej. – toto2
Dzięki za zaniedbanie bez wyjaśnienia ... @Franz: Nie było dla mnie jasne, że pytasz o model pamięci. Pozwól mi przemyśleć odpowiedź. – musiKk