Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Singleton Patterns: Eager vs Lazy Initialization

Tech 1

The Singleton pattern ensures a class has only one instance and provides a global point of access to it. Instead of relying on global variables—which can be instantiated multiple times—the class itself controls the creation and storage of its sole instance, guaranteeing uniqueness.

Class Structure

The Singleton class defines a static method, getInstance(), which returns the single instance. The constructor is private to prevent external instantiation.

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

This implementation uses double-checked locking to reduce synchronization overhead. The volatile keyword ensures visibility across threads and prevents reordering issues during object construction.

Thread Safety Considerations

Without synchronization, concurrent access from multiple threads may result in multiple instances being created. The synchronized block ensures that only one thread creates the instance, while the inner check prevents redundant instantiation after the first thread completes initialization.

Static Initialization (Eager Loading)

For scenarios where performance is critical and the cost of lazy initialization is unacceptable, use eager loading:

public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

In this approach, the instance is created when the class is loaded by the JVM, eliminating the need for runtime cheecks or synchronization. This method is simpler and inherently thread-safe but may lead to unnecessary memory usage if the instance is never used.

Lazy Initialization (Lazy Loading)

Alternatively, delay instance creation until the first call to getInstance():

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {}

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

While this conserves resources, it requires careful handling in multithreaded environments to avoid race conditions.

Choose between eager and lazy loading based on application requirements: prefer eager loading for predictable, high-performance systems; use lazy loading when resource efficiency is prioritized and instantiation cost is significant.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.