19

根据许多人的说法,除非您运行 1.5 或更高版本并使用volatile关键字,否则有些常见的 Double-Checked Locking 惯用语在 java 中已被破坏。

一个损坏的双重检查锁示例:

// 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 虚拟机的。我在 Android 上工作,经常使用采用双重检查锁定的库。dalvik VM 的内存模型是否支持这个习语?

4

2 回答 2

9

这个问题的答案意味着内存模型应该是相同的,并且新的双重检查锁定习语将起作用。

于 2011-04-19T14:27:28.967 回答
0

我找到了一篇关于这个问题的非常好的文章: http ://www.javamex.com/tutorials/double_checked_locking_fixing.shtml

它清楚地说明了修复 DCL 的 3 种方法。在你的问题中,Helper 字段应该被声明为 volatile,否则它不起作用。

在使用方面,即 RoboGucie 在你的情况下,我想我会喜欢文章中提到的类加载器方法。这对我来说更清楚,也更有效。

于 2014-02-19T15:10:12.363 回答