...
This compliant solution requires that helper
be declared volatile and class Helper
be immutable. If it were not immutable, the code would violate guideline VNA06-J. Do not assume that declaring an object a reference volatile guarantees visibility of its the members of the referenced object, and additional synchronization would be necessary. (See the next compliant solution.) And, if the helper
field were non-volatile, it would violate guideline VNA01-J. Ensure visibility of shared references to immutable objects.
...
Because the Helper
object can change state after its construction, synchronization is necessary to ensure the visibility of mutable members after initial publication. Consequently, the setN()
method is synchronized to provide the visibility of the n
field in this compliant solution. (See guideline VNA06-J. Do not assume that declaring an object a reference volatile guarantees visibility of its the members of the referenced object.)
If the Helper
class is not synchronized properly, declaring helper
volatile in the Foo
class only guarantees the visibility of the initial publication of Helper
and not of subsequent state changes. Consequently, volatile references alone are inadequate for publishing objects that are not thread-safe.
If the helper
field in the Foo
class is not declared volatile, the n
field should be declared volatile so that a happens-before relationship is established between the initialization of n
and the write of Helper
to the helper
field. This is in compliance with guideline VNA06-J. Do not assume that declaring an object a reference volatile guarantees visibility of its the members of the referenced object. This is required only when the caller (class Foo
) cannot be trusted to declare helper
volatile.
...