Support Online
Skip to main content

Java Singleton Design Pattern: Guide with Best Practices and Examples

🎯 What Will You Learn in This Guide?

This guide explains in depth the Singleton pattern, which is among Java's Creational Design Patterns.
You will learn this pattern, which allows only a single instance of a class to be created, with different approaches and safe implementation methods.


🧠 Technical Summary

Purpose: To create only one instance throughout the application and provide global access to this instance.
Area of ​​use: Logging, database connection, caching, thread pool management.
What you will learn:

  • Singleton principles
  • Eager, Static Block, Lazy and Thread-Safe approaches
  • Bill Pugh method (recommended solution)
  • Reflection and Serialization risks and ways to protect

🧩 Singleton Basics

For a class to be a Singleton:

  1. Private constructor → prevents creating new objects.
  2. Private static instance → stores a single instance.
  3. Public static access method → returns this instance to the outside world.

⚙️ 1. Early Initialization

The instance is created while the class is loaded.

public class EagerInitializedSingleton {
private static final EagerInitializedSingleton ornek = new EagerInitializedSingleton();
private EagerInitializedSingleton(){}
public static EagerInitializedSingleton getInstance() { return ornek; }
}

➡️ Simple but takes up space in memory even if it is not used.


⚙️ 2. Static Block Initialization

Similar to early startup, but provides error handling.


public class StaticBlockSingleton {
private static StaticBlockSingleton ornek;
private StaticBlockSingleton(){}
static {
try { ornek = new StaticBlockSingleton(); }
catch (Exception e) { throw new RuntimeException("Singleton hatası"); }
}
public static StaticBlockSingleton getInstance() { return ornek; }
}

➡️ Offers the advantage of exception handling, but still loads prematurely.


⚙️ 3. Lazy Initialization

The instance is created only when needed.


public class LazyInitializedSingleton {
private static LazyInitializedSingleton ornek;
private LazyInitializedSingleton(){}
public static LazyInitializedSingleton getInstance() {
if (ornek == null) ornek = new LazyInitializedSingleton();
return ornek;
}
}

➡️ Resource friendly but not safe in multi-thread environment.


⚙️ 4. Thread-Safe Singleton

Provides security in multi-threading with synchronization.


public static synchronized ThreadSafeSingleton getInstance() {
if (ornek == null) ornek = new ThreadSafeSingleton();
return ornek;
}

➡️ Thread-safe but performance cost is high.

🔄Double-Checked Locking

It only syncs during initial creation.


if (ornek == null) {
synchronized (ThreadSafeSingleton.class) {
if (ornek == null) ornek = new ThreadSafeSingleton();
}
}

➡️ Balances performance and security.


⚙️ 5. Bill Pugh Singleton (Safest Method)

It is the most efficient and safe method after Java 5.


public class BillPughSingleton {
private BillPughSingleton(){}
private static class Yardimci {
private static final BillPughSingleton ORNEK = new BillPughSingleton();
}
public static BillPughSingleton getInstance() { return Yardimci.ORNEK; }
}

➡️ Provides thread-safe and lazy loading without synchronization.


⚠️ 6. Breaking Singleton with Reflection

Reflection can access the private constructor and create a new object. To prevent this, the following check can be added to the constructor:


private Singleton() {
if (instance != null) throw new RuntimeException("Yalnızca bir örnek oluşturulabilir!");
}

➡️ Provides protection against reflection attack.


🟣 7. Enum Singleton

The safest solution suggested by Joshua Bloch:


public enum EnumSingleton {
ORNEK;
public void islemYap() { /* ... */ }
}

➡️ Immune to Reflection, JVM only produces one instance.


🧱 8. Serialization and readResolve()

Serialization can create new objects. To prevent this:


protected Object readResolve() { return getInstance(); }

➡️ The same instance is preserved after reverse serialization.


💬 Frequently Asked Questions (FAQ)

  1. What is the difference between singleton and static class?

Singleton is an object, not a static class; It can hold state.

  1. Why is Bill Pugh the best method?

Thread-safe, no lazy and no synchronization overhead.

  1. Why is readResolve() necessary?

It prevents the creation of new objects during deserialization.

  1. Where is singleton not used?

It reduces testability in multi-dependency (state-sharing) structures.

  1. Why is Enum Singleton preferred?

Provides natural protection against both Reflection and Serialization.


✅ Result

In this guide, you learned the Java Singleton design pattern with different implementation methods. Now you know which approach is suitable in terms of performance, security and flexibility.

🚀 Start your own Java project on GenixNode and test these patterns in a real environment.