The standard practice of publishing a value to other threads is assigning a constructed object to a volatile
field: as a side effect of it acting as a bidirectional memory fence, threads which read the object through such a field are guaranteed not to see a partially constructed object.
However, if all fields in a class are final
, then the call to its constructor is automatically in a happens-before relationship with any client code, without the need for a volatile
keyword on references.
There is an article by Aleksey Shipilёv about that.
In 2014, on his specific hardware, OS and Java versions, he came to this conclusion:
The performance costs for these idioms are usually drowned in all other costs. In the singleton examples above, while the costs are measurable, the cost of allocation, or the cost of additional memory dereference may greatly offset the cost of the safe initialization/publication pattern itself.