Java Singleton Class: Implementing the Singleton Design Pattern

Explore the Java Singleton Design Pattern, one of the simplest and most effective creational patterns. Learn how the Singleton pattern ensures a class has only one instance and provides a global point of access to it, making it ideal for managing shared resources.



Java - Singleton Class

Java Singleton Design Pattern

The Singleton pattern is one of the simplest design patterns in Java. It is classified as a creational pattern, providing a reliable way to create an object.

Java Singleton Class

This pattern is based on a single class responsible for creating an object while ensuring that only one object instance exists. This class offers a way to access its single instance directly, eliminating the need for multiple instantiations.

Since there is only one Singleton instance, its instance fields exist only once per class, similar to static fields. Singletons are often used to control access to shared resources like database connections or sockets. For example, if you have a license for a single database connection or your JDBC driver faces multithreading issues, the Singleton pattern ensures that only one connection is established, or only one thread can access the connection at any time.

Advantages of Singleton Design Pattern

  • It saves memory by creating only one object instance.
  • It provides global access to the instance.

Use of Singleton Design Pattern

The Singleton design pattern is applicable when you need a class that has only one instance. It is primarily utilized in multithreading and database-related applications. Some common scenarios for using the Singleton design pattern include:

  • Creating logger classes.
  • Managing configuration settings.
  • Implementing database connection pooling.
  • Creating a class for caching mechanisms.

Java Singleton Class/Design Pattern: Examples

Example 1: Basic Singleton Implementation

This implementation features a private constructor and a field to hold the Singleton instance, along with a static accessor method named getInstance(). The private field can be initialized within a static initializer block or using a simpler initializer.

Syntax

package com.tutorialsarena;

class Singleton {
private static Singleton singleton = new Singleton();

/* A private constructor prevents other classes from instantiating. */
private Singleton() { }

/* Static method to return the instance */
public static Singleton getInstance() {
    return singleton;
}

/* Other methods protected by singleton-ness */
protected void demoMethod() {
    System.out.println("demoMethod for singleton");
}
}

public class Tester {
public static void main(String[] args) {
    Singleton tmp = Singleton.getInstance();
    tmp.demoMethod();
}
}
Output

demoMethod for singleton

Example 2: Classic Singleton with Lazy Instantiation

This example illustrates a classic Singleton design pattern. The ClassicSingleton class maintains a static reference to the sole singleton instance and returns this reference from the getInstance() method. This implementation uses lazy instantiation, ensuring that the singleton instance is created only when needed.

Syntax

package com.tutorialsarena;

class ClassicSingleton {
private static ClassicSingleton instance = null;

private ClassicSingleton() {
    // Exists only to defeat instantiation.
}

public static ClassicSingleton getInstance() {
    if (instance == null) {
        instance = new ClassicSingleton();
    }
    return instance;
}

protected void demoMethod() {
    System.out.println("demoMethod for singleton");
}
}

public class Tester {
public static void main(String[] args) {
    ClassicSingleton tmp = ClassicSingleton.getInstance();
    tmp.demoMethod();
}
}
Output

demoMethod for singleton

Example 3: Thread-safe Singleton Implementation

This implementation showcases a thread-safe Singleton object creation. The ClassicSingleton class maintains a static reference to the lone singleton instance and returns this reference from the getInstance() method, which has been made thread-safe using the synchronized keyword.

Syntax

class ClassicSingleton {
private static ClassicSingleton instance = null;

private ClassicSingleton() {
    // Exists only to defeat instantiation.
}

public static synchronized ClassicSingleton getInstance() {
    if (instance == null) {
        instance = new ClassicSingleton();
    }
    return instance;
}

protected void demoMethod() {
    System.out.println("demoMethod for singleton");
}
}

public class Tester {
public static void main(String[] args) {
    ClassicSingleton tmp = ClassicSingleton.getInstance();
    tmp.demoMethod();
}
}
Output

demoMethod for singleton