Home >Java >javaTutorial >Understanding the Singleton Pattern in Java
The Java Singleton pattern is a widely used design pattern that guarantees a class has only one instance and provides a global access point to it. Think of it as a single manager overseeing a team – there's only one, and everyone interacts through that single point of contact. This article will break down the pattern's implementation and various approaches in Java.
Several approaches exist, each with its own trade-offs:
1. Lazy Initialization: Creates the instance only when it's first needed.
<code class="language-java">import java.io.Serializable; public class LazySingleton implements Serializable { private static LazySingleton instance; private LazySingleton() { if (instance != null) { throw new IllegalStateException("Instance already created"); } } public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } private Object readResolve() { return getInstance(); } }</code>
2. Thread-Safe Singleton: Uses synchronized
to ensure thread safety during instance creation.
<code class="language-java">import java.io.*; public class ThreadSafeSingleton implements Serializable { private static final long serialVersionUID = 1L; private static ThreadSafeSingleton instance; private ThreadSafeSingleton() { if (instance != null) { throw new IllegalStateException("Instance already created"); } } public static synchronized ThreadSafeSingleton getInstance() { if (instance == null) { instance = new ThreadSafeSingleton(); } return instance; } private Object readResolve() { return getInstance(); } }</code>
3. Double-Checked Locking: Optimizes thread safety by minimizing synchronization overhead.
<code class="language-java">import java.io.*; public class DoubleCheckedLockingSingleton implements Serializable { private static final long serialVersionUID = 1L; private static volatile DoubleCheckedLockingSingleton instance; private DoubleCheckedLockingSingleton() { if (instance != null) { throw new IllegalStateException("Instance already created"); } } public static DoubleCheckedLockingSingleton getInstance() { if (instance == null) { synchronized (DoubleCheckedLockingSingleton.class) { if (instance == null) { instance = new DoubleCheckedLockingSingleton(); } } } return instance; } private Object readResolve() { return getInstance(); } }</code>
4. Bill Pugh Singleton (Recommended): Uses a static inner class to ensure lazy initialization and thread safety.
<code class="language-java">import java.io.*; public class BillPughSingleton implements Serializable { private static final long serialVersionUID = 1L; private BillPughSingleton() { if (SingletonHelper.INSTANCE != null) { throw new IllegalStateException("Instance already created"); } } private static class SingletonHelper { private static final BillPughSingleton INSTANCE = new BillPughSingleton(); } public static BillPughSingleton getInstance() { return SingletonHelper.INSTANCE; } private Object readResolve() { return getInstance(); } }</code>
5. Enum Singleton (Modern Approach): Leverages the inherent thread safety and serialization handling of enums. This is often considered the best approach for its simplicity and robustness.
<code class="language-java">public enum EnumSingleton { INSTANCE; public void showMessage() { System.out.println("Hello from Enum Singleton!"); } }</code>
The above is the detailed content of Understanding the Singleton Pattern in Java. For more information, please follow other related articles on the PHP Chinese website!