I am referring to the solution for the Singleton Pattern by Bill Pugh on Wikipedia:
public class Singleton
{
// Private constructor prevents instantiation from other classes
private Singleton() {}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder
{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance()
{
return SingletonHolder.INSTANCE;
}
}
Here they have mentioned:
The inner class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that
getInstance()
is called. Thus, this solution is thread-safe without requiring special language constructs (i.e.volatile
orsynchronized
).
However, isn't there a possibility that 2 threads would call getInstance()
at the same time, which would lead to two instances of singleton being created? Isn't it safe to use synchronized
here? If yes, where should it be used in the code?
See the "How it works", in the article "Initialization on demand holder idiom" linked from the same section.
In a nutshell, here's what happens when you call getInstance()
the first time:
SingletonHolder
it has never seen referenced before.SingletonHolder
. This includes running any static initialization, which includes the singleton instance.getInstance()
at the same time will see that SingletonHolder
is already initialized. The Java spec guarantees that class initialization is thread-safe.The JLS guarantees the JVM will not initialize instance until someone calls getInstance();
and that will be thread safe because it would happen during the class initialization of SingletonHolder
.
However, since Java 5, the preferred approach involves Enum
:
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
Reference: Implementing the singleton pattern in Java
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With