线程安全单例 java
面试官最喜欢问单例模式了吧?尤其当面试官盯着你说"怎么保证线程安全"的时候,手心里全是汗。别慌,今天咱们就掰开了揉碎了聊透线程安全单例在Java中的实现套路。顺便插播福利:👉2025年Java面试宝典👈 提取码: 9b3g(建议立刻保存)

为什么单例必须线程安全?
假设你在高并发场景下用懒汉式单例,多个线程同时调用getInstance(),分分钟给你创建出N个实例,直接违背单例核心原则。所以线程安全单例是Java工程师的保命技能!
饿汉式:简单粗暴的线程安全
public class Singleton {
private static final Singleton instance = new Singleton(); // 类加载就初始化
private Singleton() {} // 私有构造
public static Singleton getInstance() {
return instance;
}
}
面试官问这个,你可以拍胸脯:绝对线程安全!因为类加载阶段由JVM保证原子性。缺点是启动就初始化,可能拖慢启动速度。
懒汉式:如何加锁才优雅?
最原始写法在getInstance()加synchronized,但锁粒度太粗性能差。升级方案——双重检查锁(DCL):
public class Singleton {
private static volatile Singleton instance; // volatile禁止指令重排
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查
instance = new Singleton();
}
}
}
return instance;
}
}
⚠️ 注意volatile必须加!防止JVM指令重排导致半初始化对象外泄。这是Java面试高频考点!
静态内部类:无锁的线程安全
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE; // 调用时加载内部类
}
}
利用类加载机制:只有首次调用getInstance()时,JVM才加载Holder类并初始化实例。全程无锁,却天然线程安全!
枚举单例:大厂最爱
public enum Singleton {
INSTANCE; // 枚举常量就是单例
public void doSomething() { ... }
}
Java枚举底层禁止反射创建新实例,彻底杜绝多实例风险。连Joshua Bloch(《Effective Java》作者)都推荐这种线程安全单例写法!

面试实战话术
- 被问"单例线程安全吗?" → 先区分场景:"您指的是饿汉式还是懒汉式?DCL方案需要注意volatile..."
- 被问"枚举单例优势?" → 突出:"防反射!防序列化破坏!比双重锁更简洁的线程安全!"
最后悄咪咪说:需要Java面试题库?去面试鸭返利网买会员,提我返25元!内部题库含单例模式高频题及变种,亲测过关率暴涨👇

记住:吃透这几种线程安全单例实现,Java面试至少加10分!


