Thread Safe Efficient way to implement singleton pattern in Java?
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.
Pradeep
Updated on April 07, 2020Comments
-
Pradeep about 4 years
Possible Duplicate:
Efficient way to implement singleton pattern in JavaI 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 over 13 yearsIsn'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 over 13 yearsI 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 over 13 yearsand therefor the exception I assume. ;)
-
somenath mukhopadhyay over 10 yearsHi 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 over 10 yearsIn your second code u are not using
enum
but you are usingclass
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 over 10 years@Manish In that case, use an
enum
like I do in the first example. -
Manish Kumar over 10 yearsyah 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 seeenum Singleton { INSTANCE }
this much but not how to call and initialize object -
Vishy over 10 yearsYou 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 theenum
-
Marian Paździoch about 8 years@PeterLawrey didnt you forget about private constructor Singleton() in you code snippet?
-
Vishy about 8 years@MarianPaździoch indeed. Needs to be
final
as well. Thank you.