【发布时间】:2011-10-21 20:48:30
【问题描述】:
我正在从事涉及大量并发编程的 Android 项目,我将实现一些自定义线程间通信的东西(来自 java.util.concurent 的那个不太适合我的目的)。
一般来说并发编程并不容易,但使用 Dalvik 似乎更难。要获得正确的代码,您应该知道一些具体的事情以及 Dalvik 出现问题的地方。我只是找不到有关 Dalvik VM 的详细文档。大多数 Android 资源(甚至 developer.android.com 都专注于平台 API,并且没有提供有关某些重要(或低级)事物的任何深入信息)。
例如,Dalvik VM 符合哪个版本的 Java 语言规范?根据答案,volatile 变量的处理是不同的,并且会影响使用 volatile 变量的任何并发代码。
已经有一些相关的问题了:
fadden 的一些回答非常有用,但我仍然想更详细、更全面地了解相关问题。
下面是我感兴趣的原始问题(如有必要,我会更新列表,因为之前问题的答案将会到来):
- 在哪里可以找到有关 Dalvik VM 的详细信息,可以为以下问题提供答案?
- Dalvik VM 符合Java 语言规范的哪个版本?
- 如果 (2) 的答案是“第三版”,那么 Dalvik 在本规范中对 Java 内存模型 的支持有多完善?尤其是对
volatile变量语义的支持如何完善? -
在Double checked locking in Android fadden 中提供以下评论:
是的。添加“volatile”关键字后,这将适用于单处理器(所有版本的 Android)和 SMP(3.0“honeycomb”及更高版本)
是不是说Samsung Galaxy SII是双核CPU,但只有Android 2.3可能会错误的执行并发代码? (当然 Galaxy 只是一个例子,问题是关于任何具有 pre-Android 3.0 平台的多核设备)
-
在Is Dalvik's memory model the same as Java's? 中,fadden 用以下句子提供答案:
就 JSR-133 而言,目前没有一个 Dalvik 的发布版本是完全正确的
这是否意味着任何现有的正确并发 Java 代码都可能在截至发布此评论之日发布的任何 Android 版本上无法正常运行?
更新#1:回复@gnat 的评论(太长也不能发表评论)
@gnat 发表评论:
@Alexey Dalvik 不符合任何 JLS 版本,因为符合要求需要通过 JCK,这不是 Dalvik 的选项。 这是否意味着您甚至不能应用标准 Java 编译器,因为它符合标准规范? 这有关系吗?如果是,怎么做?
嗯,我的问题有点模棱两可。我真正的意思是JLS 不仅是Java 编译器实现的规则,而且是任何JVM 实现的隐式 指南。实际上,例如,JLS 声明某些类型的读取和写入是 原子 操作。这对编译器编写器来说不是很有趣,因为读/写只翻译成单个操作码。但是对于任何JVM 实现来说,应该 正确实现这些操作码是必不可少的。现在你应该明白我在说什么了。虽然 Dalvik 接受并执行使用标准 Java 编译器编译的程序,但没有任何保证它们被正确地执行 (如您所料)只是因为没有人(也许 Dalvik 的开发人员除外)知道程序中使用的所有 JLS 功能是否都受到 Dalvik 的支持。
很明显 JCK 对于 Dalvik 来说不是一个选项,这没关系,但是程序员真的应该知道 JLS 的哪些 特性他们在 Dalvik 上执行代码时可能会依赖。但是文档中没有任何关于此的文字。虽然您可能期望像 =、+、-、* 等最简单的运算符可以像您期望的那样工作,但像 volatile 变量的语义这样不平凡的特性会怎么样(这在第 2 和第 2 中有所不同) JLS 第 3 版)?后者并不是您在 JLS 中尤其是在 Java 内存模型 中可能找到的最重要的东西。
【问题讨论】:
-
StackOverflow 对于这些东西都不是特别好的资源。您在询问平台实施问题; StackOverflow 倾向于专注于 Android SDK。对于您的各种问题,我推荐groups.google.com/group/android-platform。
-
请注意,fadden 是 dalvikvm 的作者,所以您可以相信他告诉您的内容。
-
@Alexey Dalvik 不符合任何 JLS 版本,因为符合要求需要通过 JCK,这不是 Dalvik 的选项。 这是否意味着您甚至不能应用标准 Java 编译器,因为它符合标准规范? 这有关系吗?如果是,怎么做?
-
从 Honeycomb (3.0) 开始,Dalvik 确实提供了所有重要的 JSR-133 保证。 Dalvik 不是 Java,因此一般不能保证 JLS,但对于
volatile和原语的分词确实有正确的行为。最近在developer.android.com/training/articles/smp.html 上提供了 Android 上的 SMP 问题概述(重点关注 C++、Dalvik 和 ARM)。 -
Volatile 是根据 JMM 实现的。您正在运行的代码太简单,无法显示细微的差异。您可以尝试 Android SMP Primer 附录 (developer.android.com/training/articles/…) 中的示例;我观察到在 Android 上没有
volatile会失败。不过,我还没有在最近的设备上尝试过。
标签: android concurrency dalvik java-memory-model