Java immutable classes vs. volatile references

128 views Asked by At

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.

  1. Is there a perfomance benefit (from the point of view of the readers) to the latter over the former?
  2. Does this mean that there is a performance cost to final fields (for example, it effectively is equivalent to volatile access not only in semantics, but in execution)?
2

There are 2 answers

0
user16782565 On BEST ANSWER

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.

0
Malt On

The short answer is that it's something worth benchmarking on your JVM, CPU. and OS of choice since the answer will depend on these factors as well as the frequency of these operations in your code (and therefore what JIT decides to do with them).

However I'd say that intuitively, with final fields the compiler has a lot more certainty about how the field is used so it can use simple, effective optimizations. It can just put a single memory barrier after a constructor with final fields to satisfy the memory guarantees.

With volatile fields, the compiler needs to do more work to figure out what's safe, and may need to avoid performing other optimizations such as reordering reads/writes.