javaintermediate

Singleton Pattern — Thread-Safe Approaches

Implement thread-safe singletons in Java: enum, holder class, double-checked locking, and eager init.

java
// 1. BEST: Enum singleton — simplest, thread-safe, serialization-safe
public enum ConfigManager {
    INSTANCE;

    private final Map<String, String> config = new HashMap<>();

    public void set(String key, String value) { config.put(key, value); }
    public String get(String key) { return config.getOrDefault(key, ""); }
}
// Usage: ConfigManager.INSTANCE.get("db.url");

// 2. Static holder (lazy, thread-safe without synchronization)
public class DatabasePool {
    private DatabasePool() {
        // initialize pool
    }

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

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

// 3. Double-checked locking (when you need constructor args)
public class CacheService {
    private static volatile CacheService instance;
    private final int maxSize;

    private CacheService(int maxSize) {
        this.maxSize = maxSize;
    }

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

Use Cases

  • Application-wide configuration managers
  • Database connection pool instances
  • Shared cache and resource management

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.