Is on-demand initialization an idiom holder thread-safe without a final modifier

I have a hunch that using the holder idiom without declaring the holder field as final is not thread safe (due to immutability working in Java). Can someone confirm this (hopefully with some sources)?

public class Something { private long answer = 1; private Something() { answer += 10; answer += 10; } public int getAnswer() { return answer; } private static class LazyHolder { // notice no final private static Something INSTANCE = new Something(); } public static Something getInstance() { return LazyHolder.INSTANCE; } } 

EDIT: I definitely want you to get statements, not just statements like β€œit works” - please explain / prove it is safe

EDIT2: a slight modification to make my point clearer - can I be sure that the getAnswer () method will return 21 regardless of the calling thread?

+6
source share
2 answers

The class initialization procedure ensures that if the static field value is set using the static initializer (i.e. static variable = someValue; ), this value is displayed for all threads:

10 - If the execution of the initializers completed normally, then get the LC, mark the class object for C as fully initialized, notify all waiting threads, release the LC and complete this procedure in normal mode.


As for your editing, imagine a situation with two threads T1 and T2 running in this order from the point of view of a wall clock:

  • T1: Something s = Something.getInstance();
  • T2: Something s = Something.getInstance(); i = s.getAnswer(); Something s = Something.getInstance(); i = s.getAnswer();

Then you have:

  • T1 gets LC, T1 starts Something INSTANCE = new Something(); that initializes the answer returns T1 LC
  • T2 is trying to get LC, but already blocked T1 => is waiting. When T1 releases LC, T2 receives LC, reads INSTANCE , then reads answer .

So, you can see that you have the right origin - before the relationship between writing and reading to answer , thanks to the LC lock.

+15
source

This is thread safe, but mutable. So anyone who gets it can assign it to another. And this is primarily a worry (even before considering thread safety).

+2
source

All Articles