Sometimes we need to have only a single instance of a class shared across an entire application. There is a special design pattern called Singleton that restricts the instantiation of a class to one object. The pattern ensures that only one instance of the class ever exists and provides global access to the instance for the outer world.
Singletons often control access to resources, such as database connections or sockets.
For example, a class which keeps a connection to a database can be written as a singleton because creating every time a connection object is bulky for memory. If it is a singleton, then your application will perform better and faster.
Another example is a class that provides a universal logger for an application. It keeps the shared log-file as the resource.
In this topic, we will consider only the basic singleton implementation.
The basic singleton in Java
The standard way to write a class according to the singleton pattern includes:
- a private constructor to defeat the creation of instances using the keyword
new
; - a private static variable of the class that is the only instance of the class;
- a public static method to return the same instance of the class; this is the global access point to the instance.
The following code implements the concepts above.
class Singleton {
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
Singleton
is a basic implementation of the considered pattern. The field instance
stores only a single instance of the class. The constructor is declared as private
to defeat instantiation. The static method getInstance
returns the same instance of the class.Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
Singleton s3 = Singleton.getInstance();
System.out.println(s1 == s2); // true because s1 and s2 refer the same object
System.out.println(s2 == s3); // true because s2 and s3 refer the same object
s1
s2
, and s3
refer the same object that is stored in the static field of Singleton
.Lazy initialization
getInstance
).class Singleton {
private static Singleton instance;
private Singleton () { }
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
getInstance
method is called for the first time. This technique ensures that singleton instances are created only when needed.The singleton pattern in Java libraries
There are a lot of Singleton examples in the Java Class Library:
To determine a singleton, see a static creational method which always returns the same instance of a class.
Popular frameworks for developing enterprise applications (such as Spring, Java EE) also use singletons.
Criticism
There are some who are critical of the singleton pattern and consider it to be an anti-pattern in that it is frequently used in scenarios where it is not beneficial, introduces unnecessary restrictions in situations where a some instance of a class is not actually required and introduces global state into an application. Use the pattern wisely when you really need a singleton.