问题描述
|
许多人认为,除非您运行1.5或更高版本并使用
volatile
关键字,否则Java有时会出现一些常见的Double-Checked Locking惯用语。
双重检查的锁样本损坏:
// broken multithreaded version
// \"Double-Checked Locking\" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
// other functions and members...
}
该示例来自本文,还提供了有关如何修复它的详细信息:
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
Pugh的上述分析是针对Java VM的。我在Android上工作,并且经常使用采用Double-Checked Locking的库。 dalvik VM的内存模型是否支持该惯用法?
解决方法
这个问题的答案意味着内存模型应该是相同的,并且新的双重检查锁定习惯用法将起作用。,我找到了有关该问题的非常好的文章:
http://www.javamex.com/tutorials/double_checked_locking_fixing.shtml
它明确说明了修复DCL的3种方法。看起来在您的问题中,应该将Helper字段声明为volatile,否则它将不起作用。
关于用法,即您的情况下的RoboGucie,我认为我更喜欢本文中提到的类加载器方法。对我来说更清晰,效率也更高。