Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Interview question

What is the Singleton design pattern and how do you implement it thread-safely in Java? Singleton design pattern क्या है और Java में इसे thread-safely कैसे implement करें?

Answer

Singleton ensures a class has exactly ONE instance and provides a global access point to it - commonly used for configuration managers, logging, and connection pools.

// UNSAFE in multi-threaded environments - two threads could both
// pass the null check simultaneously and create two instances
class UnsafeSingleton {
    private static UnsafeSingleton instance;
    private UnsafeSingleton() {}

    public static UnsafeSingleton getInstance() {
        if (instance == null) {
            instance = new UnsafeSingleton();  // race condition possible
        }
        return instance;
    }
}

// Thread-safe with synchronized (simple but has performance overhead
// on every call, even after the instance already exists)
class SynchronizedSingleton {
    private static SynchronizedSingleton instance;
    private SynchronizedSingleton() {}

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

// Double-checked locking - synchronizes only during first creation
class DoubleCheckedSingleton {
    private static volatile DoubleCheckedSingleton instance;  // volatile is essential here
    private DoubleCheckedSingleton() {}

    public static DoubleCheckedSingleton getInstance() {
        if (instance == null) {                    // first check, no locking (fast path)
            synchronized (DoubleCheckedSingleton.class) {
                if (instance == null) {              // second check, inside the lock
                    instance = new DoubleCheckedSingleton();
                }
            }
        }
        return instance;
    }
}

// BEST APPROACH - Bill Pugh Singleton using a static holder class
// (thread-safe by the JVM's class-loading guarantees, no explicit locking needed)
class BillPughSingleton {
    private BillPughSingleton() {}

    private static class Holder {
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }

    public static BillPughSingleton getInstance() {
        return Holder.INSTANCE;  // Holder loaded lazily, only on first access
    }
}

// ALTERNATIVE - Enum singleton (simplest, inherently thread-safe and serialization-safe)
enum EnumSingleton {
    INSTANCE;
    public void doSomething() { System.out.println('Working'); }
}
EnumSingleton.INSTANCE.doSomething();

Singleton यह सुनिश्चित करता है कि class का exactly एक instance हो और उस तक global access point दे - configuration managers, logging, connection pools के लिए common है।

// UNSAFE - multi-threaded environment में race condition
class UnsafeSingleton {
    private static UnsafeSingleton instance;
    private UnsafeSingleton() {}

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

// synchronized से thread-safe (हर call पर overhead)
class SynchronizedSingleton {
    private static SynchronizedSingleton instance;
    private SynchronizedSingleton() {}

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

// Double-checked locking
class DoubleCheckedSingleton {
    private static volatile DoubleCheckedSingleton instance;
    private DoubleCheckedSingleton() {}

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

// सबसे बेहतर - Bill Pugh Singleton
class BillPughSingleton {
    private BillPughSingleton() {}

    private static class Holder {
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }

    public static BillPughSingleton getInstance() {
        return Holder.INSTANCE;
    }
}

// Enum singleton - सबसे सरल, thread-safe
enum EnumSingleton {
    INSTANCE;
    public void doSomething() { System.out.println('Working'); }
}

Was this answer clear?