单例模式 双重检测机制答疑

xiaoge0103 2019-08-06 09:28:42
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}

mem = allocate(); 1 //Allocate memory for Singleton object.
singleton = mem; 2 //Note that instance is now non-null, but
//has not been initialized.
ctorSingleton(singleton ); 3 //Invoke constructor for Singleton passing
//instance.

在 JVM 的即时编译器中存在指令重排序的优化.也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2.如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。

疑问: 为什么使用了synchronized同步还会被其他线程抢占?
...全文
157 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
baichangda234 2019-08-12
  • 打赏
  • 举报
回复
这和synchronized没有关系 在同步结束之后的singleton就是为初始化完成的
沁海棠 2019-08-06
  • 打赏
  • 举报
回复
https://blog.csdn.net/qinhaotong/article/details/96302416 不知道能不能帮到你

67,550

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧