In this post we will introduce the Singleton Pattern.
In many ways, Singleton is very like the global variables. But Singleton could be lazily loaded. Singleton Pattern ensures there is at most one instance of a class and that is globally accessible. For example, we may want the database connection and logging to be a singleton.
Singleton is a class with private constructors. The only way to get an instance of it is via a static method getInstance
.
Formal Definition
The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it.
Implementation
For Single Thread (non thread-safe)
public class Singleton {
private static Singleton uniqueInstance;
// other useful instance variables here
private Singleton() {
// initialize
}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// other useful methods here
}
However, if java runs multithread, unqueInstance might be created more than once. This is not what we want.
Synchronized
It is straightforward to solve the thread safety issue by adding synchronized
keyword to getInstance method. (TODO: ...detailed explanation here... )
public class Singleton {
private static Singleton uniqueInstance;
// other useful instance variables here
private Singleton() {
// initialize
}
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// other useful methods here
}
However, synchronization is expensive.
Eager Initialization
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
// other useful instance variables here
private Singleton() {
// initialize
}
public static Singleton getInstance() {
return uniqueInstance;
}
// other useful methods here
}
If the Singleton is bound to be used, we could use eager initialization, making sure the instance is available from the start. This certainly solves the expensive synchronization issue.
However, one problem with this approach is if the Singleton is resource intensive (initialization is expensive), and we may not use it in the whole program. It is advised to turn to other methods.
Double-checked locking
public class Singleton {
private volatile static Singleton uniqueInstance;
// other useful instance variables here
private Singleton() {
// initialize
}
public static Singleton getInstance() {
if (uniqueInstance == null) {
// Check for an instance and if there isnβt one,
// enter a synchronized block.
synchronized (Singleton.class) {
// Note we only synchronize the
// first time through
if (uniqueInstance == null) {
// Once in the block, check again and if
// still null, create an instance.
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
// other useful methods here
}
If performance is an issue, use this method. However, it might be an overkill for some simpler problems.
Diagram
Singleton Pattern is probably the most simple design pattern. That's it for today. See you next post!
Top comments (0)