在Java中,单例模式(Singleton Pattern)是一种常用的设计模式,用于确保一个类只有一个实例,并提供全局访问点。为了让单例在多线程环境下保持线程安全,常用的实现方式有以下几种:
-
双重检查锁(Double-Check Locking)
通过在getInstance()方法中先检查实例是否为null,再加同步锁,内部再次检查,最终只在第一次创建时进入同步块。需要注意volatile关键字保证可见性和防止指令重排。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; } } -
静态内部类(Initialization-on-demand holder idiom)
利用类加载机制,确保实例化只在第一次调用getInstance()时发生,并天然线程安全。该方式最简洁、性能最佳。public class Singleton { private Singleton() {} private static class Holder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return Holder.INSTANCE; } } -
枚举实现
Java 枚举类型天然具备序列化安全性和线程安全。只需定义一个枚举常量即可。public enum Singleton { INSTANCE; public void doSomething() { // 业务逻辑 } }使用时:
Singleton.INSTANCE.doSomething(); -
使用
synchronized方法
直接把getInstance()方法加synchronized,简单但每次调用都会产生同步开销,适用于不频繁访问的场景。public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
选择建议
- 对性能要求极高且只需要单例一次时,推荐使用 静态内部类 或 枚举。
- 如果你想兼顾懒加载与多线程安全,双重检查锁 是经典实现。
- 若代码简洁为首要目标且对并发量不敏感,可以直接使用
synchronized方法。
通过上述实现方式,Java 中的单例模式可以在多线程环境下保持线程安全,同时避免了多实例化导致的资源浪费。

发表回复