返回

Java并发编程中双重检查锁漏洞

发布时间:2022-11-24 10:24:11 192

单例模式在实际工作或面试中出现的频率更高,double-checked lock是单例常见实现:

public class SimpleSingleton4 {

private static SimpleSingleton4 INSTANCE;

private SimpleSingleton4() {
}

public static SimpleSingleton4 getInstance() {
if (INSTANCE == null) {
synchronized (SimpleSingleton4.class) {
if (INSTANCE == null) {
INSTANCE = new SimpleSingleton4();
}
}
}
return INSTANCE;
}
}

这段代码有问题:


public static SimpleSingleton4 getInstance() {
if (INSTANCE == null) {//1
synchronized (SimpleSingleton4.class) {
//2
if (INSTANCE == null) {
//3
INSTANCE = new SimpleSingleton4();
//4
}
}
}
return INSTANCE;
//5
}

你希望按1, 2, 3, 4, 金额 5顺序执行。

但是Java虚拟机实际上会做一些优化,重新排列一些代码指令。重排后的顺序可能会变成: 1, 3, 2, 4, 5,这样在多线程的情况下也会创建多个实例。重新排列的代码可能如下所示:


public static SimpleSingleton4 getInstance() {
if (INSTANCE == null) {//1
if (INSTANCE == null) {
//3
synchronized (SimpleSingleton4.class) {
//2
INSTANCE = new SimpleSingleton4();
//4
}
}
}
return INSTANCE;
//5
}

有什么解决办法?

答:您可以将volatile关键字添加到 的定义中INSTANCE。具体代码如下:

public class

private volatile static SimpleSingleton7 INSTANCE;

private SimpleSingleton7() {
}

public static SimpleSingleton7 getInstance() {
if (INSTANCE == null) {
synchronized (SimpleSingleton7.class) {
if (INSTANCE == null) {
INSTANCE = new SimpleSingleton7();
}
}
}
return INSTANCE;
}

} 关键字可以保证多线程的volatile可见性但不保证原子性,也可以禁止指令重排序。

双重检查锁的机制不仅保证了线程安全,而且相比直接锁,提高了执行效率,节省了内存空间。

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
Java并发编程如何防止死锁? 2022-11-24 09:48:14