Answer
Singleton Design Pattern in Java
Basic Singleton (Lazy Initialization)
Java
public class Singleton {
// Static variable holds the single instance
private static Singleton instance;
// Private constructor prevents instantiation from outside
private Singleton() {
System.out.println("Singleton instance created");
}
// Public static method to get/create the instance
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // create only if not exists
}
return instance;
}
public void showMessage() {
System.out.println("Hello from Singleton!");
}
}
public class SingletonDemo {
public static void main(String[] args) {
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
Singleton obj3 = Singleton.getInstance();
obj1.showMessage();
// All references point to the SAME object
System.out.println("obj1 == obj2: " + (obj1 == obj2)); // true
System.out.println("obj1 == obj3: " + (obj1 == obj3)); // true
System.out.println("Hashcode: " + obj1.hashCode() + " == " + obj2.hashCode());
}
}
Output
CODE
Singleton instance created
Hello from Singleton!
obj1 == obj2: true
obj1 == obj3: true
Hashcode: 366712642 == 366712642
Thread-Safe Singleton (Double-Checked Locking)
Java
public class ThreadSafeSingleton {
// volatile ensures visibility across threads
private static volatile ThreadSafeSingleton instance;
private ThreadSafeSingleton() {}
public static ThreadSafeSingleton getInstance() {
if (instance == null) { // first check (no lock)
synchronized (ThreadSafeSingleton.class) { // lock only when needed
if (instance == null) { // second check (with lock)
instance = new ThreadSafeSingleton();
}
}
}
return instance;
}
}
Eager Initialization (Simplest Thread-Safe)
Java
public class EagerSingleton {
// Created when class loads — always thread-safe
private static final EagerSingleton INSTANCE = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return INSTANCE;
}
}
Real Automation Example: WebDriver Manager Singleton
Java
public class DriverManager {
private static DriverManager instance;
private WebDriver driver;
private DriverManager() {}
public static DriverManager getInstance() {
if (instance == null) {
instance = new DriverManager();
}
return instance;
}
public WebDriver getDriver() {
if (driver == null || ((ChromeDriver) driver).getSessionId() == null) {
driver = new ChromeDriver();
driver.manage().window().maximize();
}
return driver;
}
public void quitDriver() {
if (driver != null) {
driver.quit();
driver = null;
}
}
}
// Usage in any test or page object:
WebDriver driver = DriverManager.getInstance().getDriver();
Singleton with ThreadLocal for Parallel Tests
Java
public class ParallelDriverManager {
// Each thread gets its OWN driver instance
private static ThreadLocal<WebDriver> driverThread = new ThreadLocal<>();
public static void setDriver(WebDriver driver) { driverThread.set(driver); }
public static WebDriver getDriver() { return driverThread.get(); }
public static void removeDriver() { driverThread.remove(); }
}
When to Use Singleton
| Use Case | Example |
|---|---|
| WebDriver management | One driver per test class |
| Configuration reader | Read config.properties once |
| Logger | Single log writer |
| Database connection | Single connection pool |
| Report manager | Single Extent report |
