要使Double Checked Locking双重检查锁模式正常工作,JDK必须>=1.5, 并且使用volatile关键字。
http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html
这篇文章介绍了为什么Double Checked Locking会不工作。
// Broken -- Do Not Use!
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
}
}
return helper;
}
从代码的语义看, 代码先创建了Helper的实例,然后赋值(write)给变量helper。然而代码在实际运行时,JIT编译器不会保证类的初始化会在变量赋值(write)之前完成。这时候,如果有其它线程在变量赋值和Helper实例创建完成之间读取helper,就会发生问题。
JDK1.5之后volatile增加了新功能,就是会严格控制volatile变量读写的顺序,JIT生成指令时不会打乱读写之前或者之后的顺序(之前的或者之后的可以被打乱),这样就能保证在写helper之前,Helper已经实例化完成。
双重检查锁定正确用法
本文探讨了双重检查锁定(DoubleCheckedLocking)模式在多线程环境下正确实现的方法。为确保模式有效,JDK版本须为1.5及以上,并利用volatile关键字防止编译器对内存操作进行优化,从而避免潜在的并发问题。
2755

被折叠的 条评论
为什么被折叠?



