The essential concept behind the singleton design pattern is to have no more than one instance of the target class at any given time per java virtual machine. That involves minor modifications to our regular java class that we intend to convert to a singleton class.
A singleton class itself is not thread safe. Multiple threads can access the singleton same time and create multiple objects, violating the singleton concept. The singleton may also return a reference to a partially initialized object.
When implementing a singleton class, we have to place certain restrictions on instantiating objects from our singleton class.
The caller must not be able to instantiate the object by calling the new operator. This direct instantiation is defeated by providing a private constructor, disallowing the use of new outside the class.
Here is a singleton class. But it is not thread-safe
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
To get the instance of the singleton class, we call the static method
If you analyze the above code carefully, you will notice some thread safety issues when multiple threads try to access our singleton. To prevent concurrent multi-threaded access, each thread must obtain a lock to access the
The problems we face are:
The short answer is a singleton can be made thread-safe by instantiating the singleton class inside a static inner class or static initializer block.
If you are looking for a thread-safe singleton, the code below achieves it by implementing a static inner class. It does thread-safe lazy-initialization of the object without explicit synchronization.
Note that the variable
public class Singleton {
private static class LoadSingleton {
static final Singleton INSTANCE = new Singleton();
}
private Singleton() {}
public static Singleton getInstance() {
return LoadSingleton.INSTANCE;
}
}
The below code illustrates how to implement a thread-safe singleton class in java using a static initializer block. The only difference is the way the instance is created. Static initializer block vs. static inner class.
public class Singleton {
private final static Singleton instance;
static {
instance = new Singleton();
}
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
The concept of the Singleton pattern has always been a debatable topic. My in-depth research reveals very few acceptable reasons to use a singleton class. In most cases, the framework you use most likely has an out-of-the-box solution in place. Some examples are logging, cache, configuration, and database connection pools that provide a global point of access to that instance throughout the application.