volatile
从单例模式引出
单例模式一文中,DCL实现单例使用了关键了volatile:
class Singleton5 {
private Singleton5() {
System.out.println("private Singleton3");
}
private static volatile Singleton5 INSTANCE = null;
public static Singleton5 getInstance() {
if (INSTANCE == null) {
synchronized (Singleton5.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton5(); // *
}
}
}
return INSTANCE;
}
}
*处的代码反编译后的字节码指令为:
1: new // 给Singleton5这个对象分配空间
2: invokespecial // Method "<init>":()V 执行构造函数
3: putstatic // 将内存空间的地址赋值给对应的引用,也就是这里的INSTANCE
由于2和3这两个指令并没有依赖关系,所以CPU在执行的时候可能会发生指令重排序,即以这种顺序执行:
1: new // 给Singleton5这个对象分配空间
3: putstatic // 将内存空间的地址赋值给对应的引用,也就是这里的INSTANCE
2: invokespecial // Method "<init>":()V 执行构造函数
那么假设现在有两个线程执行这段代码,并且按照顺序执行:
线程1 线程2
new 分配空间
INSTANCE = 对象
if (INSTANCE == null)
return INSTANCE
Singleton5() 初始化
这样线程2拿到的对象就是没有初始化过对象,可能会出现问题。
说明
===================================
仅作为校招时的《个人笔记》,详细内容请看【参考】部分
===================================
参考
- B站,黑马满老师
- 《深入理解Java虚拟机》第3版
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~