Ensure a class only has one instance, and provide a global point of access to it. - GOF

All singleton implementations offer NO public constructor but only private constructor to enforce non-instantiability. In Java, however, because a private constructor can still be accessed through a backdoor of using reflection, you want to add extra check in the private constructor to guard against reflection vulnerability (see examples below).

The Singleton object is not created until Singleton.INSTANCE is referenced.

[1] Static variable INSTANCE will be initialized when Singleton.INSTANCE is referenced (requested).[2] The extra check on whether INSTANCE is null or not in the private constructor is to guard against reflection attack which is how multiple instances may be instantiated is now prevented.

approach #2

Is this approach thread-safe? Yes.

Another way is to make this static final member private with a public static factory-method (getInstance()) to return the sole singleton instance:

The Singleton object is also not created until a call is made to the static getInstance() method to reference the static member field INSTANCE.

One of the advantages of this factory-method approach over the first approach is that you can later change the implementation of getInstance() without clients needing to change the interface of calling it. For example, instead of returning a sole instance per classloader, your can extend to make getInstance() to return a sole instance per thread.

approach #3

Is this approach thread-safe? Yes.

Both approach #1 and #2 initialize a static field to ensure that the Singleton object is not created until Singleton.INSTANCE is referenced or when a call is made to the static getInstance() method. This is a good approach because such Singleton implementations are thread-safe when it comes to getting a reference to the Singleton instance. Otherwise, should you not initialize the static member field via declaration, you'll have to assure thread-safe via synchronization as in this approach:

approach #4

Is this approach thread-safe? Yes.Both serializable and deserializable? Yes.

A forth and better way of implementing Singleton is to use a single-element Enum type (available in Java 1.6+). Enum constants (e.g. INSTANCE) are implicitly static and final so you can not change INSTANCE value once created. The constructor of enum in java must be private to hide it. Utilize it to wrap around the singleton object you'd like to assure singleton and return it.

[1] enum is automatically Serializable according to its javadoc.[2] Initialize the connection when enum (Singleton.INSTANCE) is referenced for the first time.

To get a reference to the singleton object, use Singleton.getInstance() or Singleton.INSTANCE. To get the connection, do Singleton.INSTANCE.getConnection().

This single-element Enum provides an guarantee against multiple instantiation, and hold up pretty well in the face of sophisticated serialization or reflection attacks, making it the recommended approach of all approaches.

serializable singleton

Without extra consideration, most of the above approaches serializable does not make the deserialization back to a Singleton unless you add readResolve() implementation (more details see my Java Serialization post) to your serializable class so that when Singleton is deserialized, the returned object is a guaranteed singleton:

[1] The readResolve method is called when ObjectInputStream has read an object from the stream and is preparing to return it to the caller. It should not be explicitly called other than by the deserialization runtime.

The "enum approach" does comes an guarantee against multiple instantiation without needing extra code, making it serializable singleton by default for free.

discussion

Some consider Singleton an anti-pattern because it couples your code with specific implementation.

Here's a scenario: Whenever a client retrieves a singleton's instance, that client becomes undesirably coupled with the fact that its supplier is a specific type of singleton. For example, in the following code snippet, the Client can no longer easily 'deploy' by swapping in a different kind of Deployer because the principle of "programming to an interface, not an implementation" is violated.