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?