5 Ways to implement Singleton Design Pattern in Java

This article introduces the singleton design pattern and its 5 implementation variations in Java You will learn different ways to implement a singleton pattern and also understand the challenges with creating a singleton class like thread-safety issues and serialization issues.

Problem
At most one instance of a class must be created in an application.

Solution
That class (singleton) is defined including its own instance, and the constructor must be private.




What is Singleton Design Pattern in Java?

Singleton Design Pattern is a popular pattern to keep a global variable. It's a class with a getInstance() method which is both public and static so that any class which needs a reference to this class can call this method and get the global reference.

Btw if you are interested in learning more about design patterns then you can also see the Design Pattern in Java course by Dmitri Nestruck on Udemy to learn more about design patterns and their modern implementations. It's one of the best courses and contains modern implementations of classic Java design patterns using modern features.

Here is the UML diagram of Singleton design pattern in Java and then we'll see how you can implement Singleton pattern in Java:

5 Ways to implement Singleton Design Pattern in Java


1. Lazy initialization, non-thread-safe:

This is the classical version, but it's not thread-safe. If more than one thread attempts to access instance at the same time, more than one instance may be created.


public class Singleton {
    private static Singleton instance = null;
    public static Singleton Instance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
    private Singleton() {}
}



2. Non-lazy initialization, thread-safe

This is the simplest thread-safe version, but it does not support lazy initialization.

public class Singleton {
    private static volatile  Singleton instance = new Singleton();
    public static Singleton Instance() {
        return instance;
    }
    private Singleton() {}
}


3. Lazy initialization, thread-safe

This version supports both properties but has performance problems. Once a thread uses a singleton instance, the others have to wait because of the lock.


public class Singleton {
    private static Singleton instance = null;
    private static readonly object lockObj = new object();
    public static Singleton Instance() {
        lock (lockObj) {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }
    private Singleton() {}
}



4. Double-check locking

An improved version of the third solution. Two null controls prevent lock waits for the most time, but not always. Also, it does not work properly for Java because of the Java memory management approach.


public class Singleton {
    private static Singleton instance = null;
    private static object lockObj = new object();
    public static Singleton Instance() {
        if (instance == null) {
            lock (lockObj) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
    private Singleton() {}
}



5. Nested initialization

A nested class is used for lazy initialization. This version is also thread-safe, but a bit complex. For most situations, solutions 2 or 4 will be suitable according to performance parameters.


public class Singleton {
    public static Singleton Instance() {
         return Nested.instance;
    }
    private Singleton() {}

    class Nested {
        static Nested() {}
        internal static readonly Singleton instance = new Singleton();
    }
}

Usage:

public static void main (string[] args) {
    Singleton instance = Singleton.Instance();
}

That's all about how to implement the Singleton Design Pattern in Java. I have shown you 5 different implementations of the Singleton pattern in Java. You can use any of the above methods to create Singleton for your project, though I recommend Enum Singleton pattern because of its simplicity and full proof nature.

Further Learning
Design Pattern Library
Web Application Architecture 101
Java Design Patterns - The Complete Masterclass


If you like this article and interested in learning more about design patterns and principles, you may like following ones as well :

  • 5 Free Courses to learn Object Oriented Programming (courses)
  • What is the difference between Adapter, Decorator, and Proxy design patterns? (answer)
  • Why implementing Singleton using Enum is better than Class in Java? (answer)
  • What is the difference between Association, Aggregation, and Composition in OOP? (answer)
  • What is the Open-Closed design Principle in OOP? (answer)
  • What is the difference between Factory and Abstract Factory Design Patterns? (answer)
  • 5 Reasons to use Composition in place of Inheritance in Java? (answer)
  • How to implement the Strategy Design Pattern using Java Enum? (solution)
  • What is the difference between State and Strategy patterns in Java? (answer)
  • How to implement the Builder design pattern in Java? (solution)
  • 10 Object-Oriented Design Principle Every Programmer Should know (principles)
  • Top 5 Books to Learn Design Patterns and Principles (books)
  • How to implement DAO design Pattern in Java? (answer)
  • What is the difference between Singleton and Static Class in Java? (answer)
  • Why should you Interface for Coding in Java? (answer)
  • A real-life example of the Decorator Pattern in Java? (example)
  • 5 Online Courses to learn Design Pattern in Java (courses)

Thanks for reading this article so far. If you like this article about the Singleton Pattern in Java, then please share it with your friends and colleagues. If you have any questions or feedback, then please drop a note.

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.