在Java中,getInstance()方法是单例模式的核心,用于获取类的唯一实例。在并发环境下,为了确保线程安全,我们需要对getInstance()方法进行同步控制。以下是几种常见的并发控制方法:
- 使用synchronized关键字:
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
这种方法简单,但可能导致性能问题,因为在多线程环境下,每次调用getInstance()方法都需要等待锁释放。
- 使用双重检查锁定(Double-Checked Locking):
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
这种方法在第一次检查时不需要获取锁,只有在实例为null时才需要获取锁并创建实例。这样可以减少同步带来的性能开销。注意,这里使用了volatile关键字来确保instance变量的可见性。
- 使用内部静态类(Inner Static Class):
public class Singleton { private Singleton() {} private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }
这种方法利用了Java类加载机制,当getInstance()方法被调用时,才会加载SingletonHolder类并创建实例。这样可以确保线程安全和延迟加载,同时避免了同步带来的性能开销。
- 使用枚举(Enum):
public enum Singleton { INSTANCE; // 其他方法 }
这种方法简单且线程安全,因为枚举类型的实例在类加载时就已经创建,而且Java枚举类型天然支持单例模式。同时,枚举类型还提供了其他内置方法,如values()和valueOf(),方便扩展。