Java Android中的双重检查锁定

Java Android中的双重检查锁定,java,android,virtual-machine,dalvik,double-checked-locking,Java,Android,Virtual Machine,Dalvik,Double Checked Locking,根据许多人的说法,java中比较常见的双重检查锁定习惯用法已被打破,除非运行1.5或更高版本并使用volatile关键字 损坏的双重检查锁示例: // Broken multithreaded version // "Double-Checked Locking" idiom class Foo { private Helper helper = null; public Helper getHelper() { if (helper == null) synch

根据许多人的说法,java中比较常见的双重检查锁定习惯用法已被打破,除非运行1.5或更高版本并使用
volatile
关键字

损坏的双重检查锁示例:

// 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...
  }
该示例来自本文,其中还提供了有关如何修复它的详细信息:


上面Pugh的分析是针对Java虚拟机的。我在Android上工作,经常使用采用双重检查锁定的库。dalvik VM的内存模型支持这个习惯用法吗?

对这个问题的回答意味着内存模型应该是相同的,新的双重检查锁定习惯用法会起作用。

我发现了一篇关于这个问题的非常好的文章:

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


在使用方面,例如在你的例子中的RoboGucie,我想我会倾向于文章中提到的类装入器方法。这对我来说更清楚,也更有效。

是的。通过添加“volatile”关键字,这将在uniprocessor(所有版本的Android)和SMP(3.0“honeycomb”及更高版本)上运行。否则,在honeycomb之前,是否可以对非volatile字段进行双锁检查@顺便问一下,dalvik java.lang.Class类中是否存在任何反射调用缓存?通过缓存,我的意思是在java虚拟机上有一些字节码生成:stackoverflow.com/a/414823/693752您需要使用某种同步操作(
volatile
synchronized
,等等),如Pugh的站点所示。问题中的坏例子是坏的,不应该使用。随着时间的推移,Dalvik中反射的实现已经发生了相当大的变化,因此您必须查看给定版本的代码才能确切了解它的功能。我相信有一些缓存,但据我所知,字节码生成不是使用的技术之一。@DanieleSegato我相信这回答了你在另一个答案上的问题。我对艺术的行为没有直接的了解,但没有理由相信它不能正确处理这个问题。你可能可以猜到我在看什么;)