Sikker udgivelse af uforanderlige objekter i Java
Nej, du er ikke garanteret, at du vil se alle opdateringer til toShare
felt af dine delte data. Dette skyldes, at dine delte data ikke bruger nogen synkroniseringskonstruktioner, der garanterer deres synlighed eller synligheden af referencer, der kan nås gennem dem på tværs af tråde. Dette gør det åbent spil for adskillige optimeringer på compiler- og hardwareniveau.
Du kan roligt ændre din toShare
felt for at henvise til en String
(som også er uforanderlig til alle dine formål), og du vil sandsynligvis (og korrekt) føle dig mere utryg ved dens opdateringssynlighed.
Her kan du se et rudimentært eksempel, jeg har lavet, der kan vise, hvordan opdateringer går tabt uden yderligere foranstaltninger til at publicere ændringer til referencen for et uforanderligt objekt. Jeg har kørt det ved hjælp af -server
JVM-flag på JDK 8u65 og Intel® Core™ i5-2557M, idet der ses bort fra den muligvis kastede NullPointerException
og så følgende resultater:
- Uden
safe
ervolatile
, den anden tråd afsluttes ikke, fordi den ikke kan se mange af ændringerne foretaget af den første tråd
Konsoloutput:
[T1] Shared data visible here is 2147483647
- Når
safe
ændres tilvolatile
, den anden tråd ender sammen med den første tråd
Konsoloutput:
[T1] Shared data visible here is 2147483647
[T2] Last read value here is 2147483646
[T2] Shared data visible here is 2147483647
P.S. Og et spørgsmål til dig - hvad sker der, hvis sharedData
(og ikke safe
) er lavet volatile
? Hvad kunne der ske ifølge JMM?