3

Is below code correct example of thread safe Singleton pattern in Java ?

    class Singleton {
    private static Singleton INSTANCE = new Singleton();

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

Since static members are initialised, only once, at the time of class loading by JVM which is guaranteed to be thread safe, so does this not make above code example of thread safe Singleton class(Early loading) ?

Is there anything wrong with above statement ? If yes, then what minimum changes are required to convert it to thread safe Singleton class ?

userv
  • 2,527
  • 4
  • 27
  • 36
  • 1
    it is perfectly thread safe. – davidxxx Feb 12 '18 at 12:17
  • 2
    You are correct in your statement regarding the initialisation of this class, however the instance is not final, and as such some unforeseen behaviour may occur when you assign another object to the variable. – Lewis_McReu Feb 12 '18 at 12:17
  • please refer => http://javarevisited.blogspot.in/2014/05/double-checked-locking-on-singleton-in-java.html – Vikrant Kashyap Feb 12 '18 at 12:31
  • 1
    you may also take a look to => http://javarevisited.blogspot.in/2012/12/how-to-create-thread-safe-singleton-in-java-example.html – Vikrant Kashyap Feb 12 '18 at 12:31
  • Thanks Vikrant. first link refers only to lazy initialisation examples where as 2nd link has mentioned the exact thing – userv Feb 12 '18 at 12:44
  • The simplest solution is `enum Singleton { INSTANCE }` It's thread safe, lazy initialising and less error prone e.g. you can't create a `new Singleton()` or `new Singleton() { }` sub class. – Peter Lawrey Feb 12 '18 at 14:00

1 Answers1

2

This is guaranteed to be safe by the JLS. See the holder pattern: "since the class initialization phase is guaranteed by the JLS to be sequential, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization."

The holder pattern is more complex than what you want, but the important part is that static final Something INSTANCE = new Something() is safe no matter which class it is declared in. The benefit of the holder pattern compared to what you have is that the singleton won't be initialized until the first time it is used. This is helpful if you want to access other static members in your Singleton class when the cost of initializing the Singleton instance is expensive.

As Lewis_McReu and user6690200 pointed out, you should declare the INSTANCE field final in order to ensure that you don't accidentally assign a different Singleton instance to the variable. You should also declare a private no-argument Singleton() constructor to prevent other instances from being created. To make it even more bulletproof, you should declare the Singleton class final so that you can't subclass it with a public constructor.

Kevin Jin
  • 1,536
  • 4
  • 18
  • 20
  • you refer to Initialization-on-demand holder idiom in your link. It is not lazy in the OP code. – davidxxx Feb 12 '18 at 12:19
  • The important part is that `static final Something INSTANCE = new Something()` is safe, no matter what class it is declared in. – Kevin Jin Feb 12 '18 at 12:20
  • Even if it is not `final`, it is thread-safe as far as initialization is concerned. It is dangerous in other ways however. – Kevin Jin Feb 12 '18 at 12:24
  • So not declaring the member variable final will prevent it from being thread safe Singleton ? Is final necessary ? – userv Feb 12 '18 at 12:32
  • 1
    All singleton references should be declared `final` since by definition there should only be one instance ever created, so it makes no sense to reserve the ability to reassign the reference (unless you want to conditionally `null` it out at some future point in time). – Kevin Jin Feb 12 '18 at 12:34
  • 1
    To answer your question, it won't change the behavior of the code you posted. However, marking the field `final` will prevent you from accidentally writing something like `void setInstance(Singleton o) { INSTANCE = o; }`, which can be thread-unsafe, and is also very wrong for other reasons. – Kevin Jin Feb 12 '18 at 12:57
  • I could say even if it is `final`, it is not thread-safe as far as modification is concerned if this class is not immutable. – grape_mao Feb 12 '18 at 13:36