Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Initialization On Demand Holder idiom 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 the way immutability works in Java). Can somebody 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 sourced statements, not just assertions like "it works" -- please explain/prove it's safe

EDIT2: A little modification to make my point more clear - can I be sure that the getAnswer() method will return 21 regardless of calling thread?

like image 994
Jakub Bochenski Avatar asked Jan 08 '14 11:01

Jakub Bochenski


2 Answers

The class initialization procedure guarantees that if a static field's value is set using a static initializer (i.e. static variable = someValue;) that value is visible to all threads:

10 - If the execution of the initializers completes normally, then acquire LC, label the Class object for C as fully initialized, notify all waiting threads, release LC, and complete this procedure normally.


Regarding your edit, let's imagine a situation with two threads T1 and T2, executing in that order from a wall clock's perspective:

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

Then you have:

  • T1 acquire LC, T1 run Something INSTANCE = new Something();, which initialises answer, T1 release LC
  • T2 tries to acquire LC, but already locked by T1 => waits. When T1 releases LC, T2 acquire LC, reads INSTANCE then reads answer.

So you can see that you have a proper happens-before relationship between the write and the read to answer, thanks to the LC lock.

like image 140
assylias Avatar answered Oct 04 '22 03:10

assylias


It is thread-safe for sure, but is mutable. So anyone who gets it may assign it to something else. And that is first thing to worry about (even before considering thread-safety).

like image 35
peter.petrov Avatar answered Oct 04 '22 02:10

peter.petrov