Safe publication of immutable objects in Java
No, you are not guaranteed that you'll be seeing all updates to the toShare
field of your shared data. This is because your shared data does not use any synchronization constructs that guarantee its visibility or the visibility of references reachable through it across threads. This makes it open game for numerous optimizations on the compiler and hardware level.
You can safely change your toShare
field to reference a String
(which is also immutable for all your purposes) and you'll probably (and correctly) feel more uneasy about its update visibility.
Here you can see a rudimentary example I've created that can show how updates are lost without any additional measures to publish changes to the reference of an immutable object. I've ran it using the -server
JVM flag on JDK 8u65 and Intel® Core™ i5-2557M, disregarding the possibly thrown NullPointerException
and saw the following results:
- Without
safe
beingvolatile
, the second thread doesn't terminate because it doesn't see many of the changes made by the first thread
Console output:
[T1] Shared data visible here is 2147483647
- When
safe
is changed to bevolatile
, the second thread terminates alongside the first thread
Console output:
[T1] Shared data visible here is 2147483647
[T2] Last read value here is 2147483646
[T2] Shared data visible here is 2147483647
P.S. And a question to you - what happens if sharedData
(and not safe
) is made volatile
? What could happen according to the JMM?