Thread Safe Efficient way to implement singleton pattern in Java?

25,155

Solution 1

The most efficient/simplest way to make a lazy loading Singleton is just

enum Singleton {
   INSTANCE
}

Note: there is no need for locking as class loading is thread safe. The class is final by default and the constructor cannot be called via reflection. The INSTANCE will not be created until the INSTANCE, or the class is used. If you are worried the class might be accidentally used you can wrap the singleton in an inner class.

final class Singleton {
    private Singleton() { }
    static class SingletonHolder {
        static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

IMHO, you have to be pretty paranoid to consider this a better solution.

Solution 2

A lot has been written about this issue. Yes, the simple double-check-locking pattern is not safe. But you can make it safe by declaring the static instance as volatile. The new Java Memory Model specification adds some code-reordering restrictions for compilers when dealing with volatile, therefore the original risks are gone.

Anyway, I rarely really need this kind of lazyness when creating the instance, so I usually simply create it statically at class-loading time:

private static MyClass instance = new MyClass();

This is short and clear. As an alternative, if you really want to make it lazy, you can take advantage of the class loading characteristics and do this:

public class MyClass {
    private static class MyClassInit {
        public static final MyClass instance = new MyClass();
    }

    public static MyClass getInstance() {
        return MyClassInit.instance; 
    }
...
}

The nested class will not be loaded until the first time you call getInstance().

Solution 3

The first code sample in the accepted answer for Efficient way to implement singleton pattern in Java is thread safe. The creation of the INSTANCE is performed by the class loader the first time the class is loaded; it's performed exactly once, and in a thread-safe way:

public final class Foo {

    private static final Foo INSTANCE = new Foo();

    private Foo() {
        if (INSTANCE != null) {
                throw new IllegalStateException("Already instantiated");
        }
    }

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

(copied from What is an efficient way to implement a singleton pattern in Java?)

The 2nd code sample in the question is correct and thread-safe, but it causes synchronization on each call to getInstance(), which affects performance.

Share:
25,155
Pradeep
Author by

Pradeep

Updated on April 07, 2020

Comments

  • Pradeep
    Pradeep about 4 years

    Possible Duplicate:
    Efficient way to implement singleton pattern in Java

    I was reading this Best Singleton Implementation In Java, but its not thread safe.

    As per wiki :

    if(singleton==null) { synchronized(Singleton.class) { // this is needed if two threads are waiting at the monitor at the // time when singleton was getting instantiated if(singleton==null) singleton= new Singleton(); }
    }

    But Find Bugs utility gives two errors in this : 1. Double null check. 2. Incorrect lazy initialization of static field.

    What is the best way,

    Is it Correct :

    synchronized (Singleton.class) {
    if (singleton== null) {
    singleton= new Singleton();
    }
    }
    
  • Vishy
    Vishy over 13 years
    Isn't protecting the private constructor is fairly paranoid. I assume its to avoid creating another instance using reflection, or is it to stop inner classes calling the constructor?
  • Eli Acherkan
    Eli Acherkan over 13 years
    I was discussing an answer from a previous question, so I copied the code as-is. Personally I would omit the if (INSTANCE != null) check as well.
  • Vishy
    Vishy over 13 years
    and therefor the exception I assume. ;)
  • somenath mukhopadhyay
    somenath mukhopadhyay over 10 years
    Hi Eli, from your answer i understand there will be a single copy of the Foo object. But suppose two threads call the getInstance() function at the same time. then i believe there will be a race condition. how to avoid that.hence we need to avoid that. Please have a look at [link]stackoverflow.com/questions/15930633/… to get the final answer...
  • Manish Kumar
    Manish Kumar over 10 years
    In your second code u are not using enum but you are using class so i am confused how to take it. I want to make a enum to initialize a class once and call that object every next time.How can i do that.Can you please give an example in detail
  • Vishy
    Vishy over 10 years
    @Manish In that case, use an enum like I do in the first example.
  • Manish Kumar
    Manish Kumar over 10 years
    yah that is ok but how can I initialize a class just once and use that instance every next time using enum. that is my confusion.every where i just see enum Singleton { INSTANCE } this much but not how to call and initialize object
  • Vishy
    Vishy over 10 years
    You can use Singleton.INSTANCE anywhere in your code. The code, which is called once in a thread safe way, to initialise this instance will be in your constructor for the enum
  • Marian Paździoch
    Marian Paździoch about 8 years
    @PeterLawrey didnt you forget about private constructor Singleton() in you code snippet?
  • Vishy
    Vishy about 8 years
    @MarianPaździoch indeed. Needs to be final as well. Thank you.