【问题标题】:Double checked locking in AndroidAndroid中的双重检查锁定
【发布时间】:2011-08-08 16:39:27
【问题描述】:

根据许多人的说法,Java 中有些常见的 Double-Checked Locking 习惯用法已被破坏,除非您运行的是 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...
  }

示例来自这篇文章,其中还提供了有关如何修复它的详细信息: http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

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

【问题讨论】:

  • 你大概能猜到我在看哪个;)

标签: java android virtual-machine dalvik double-checked-locking


【解决方案1】:

question 的答案暗示内存模型应该相同,并且新的双重检查锁定习语将起作用。

【讨论】:

  • 是的。添加“volatile”关键字后,这将适用于单处理器(所有版本的 Android)和 SMP(3.0“honeycomb”及更高版本)。
  • 否则,在蜂窝之前,是否可以使用非易失性字段进行双重锁定检查? @Fadden BTW,dalvik java.lang.Class 类中是否有任何反射调用缓存?通过缓存,我的意思是在 java VM 上会生成一些字节码:stackoverflow.com/a/414823/693752
  • 您需要使用某种同步操作(volatilesynchronized 等),如 Pugh 网站上所示。问题中的损坏示例是损坏的,不应使用。随着时间的推移,Dalvik 中反射的实现发生了相当大的变化,因此您必须查看给定版本的代码才能确切知道它的作用。我相信有一些缓存,但据我所知,字节码生成不是使用的技术之一。
  • @DanieleSegato 我相信这回答了您对另一个答案的问题。我对 Art 的行为没有直接的了解,但没有理由相信它不会正确处理这个问题。
【解决方案2】:

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

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

在使用方面,例如您的 RoboGucie,我想我更喜欢文章中提到的类加载器方法。这对我来说更清楚,也更有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多