我正在处理涉及大量并发编程的 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
尤其是对变量语义的支持如何完善? 在Android 中的双重检查锁定中,fadden提供以下评论:
是的。添加“volatile”关键字后,这将适用于单处理器(所有版本的 Android)和 SMP(3.0“honeycomb”及更高版本)
这是否意味着具有双核 CPU 但只有 Android 2.3 的三星 Galaxy SII可能会错误地执行并发代码?(当然 Galaxy 只是一个例子,问题是关于任何具有 pre-Android 3.0 平台的多核设备)
在Dalvik 的内存模型与 Java 的相同吗?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 的一个选项,这没关系,但程序员真的应该知道在 Dalvik 上执行代码时他们可能依赖JLS的哪些功能。但是文档中没有任何关于此的文字。虽然您可能期望像 =、+、-、* 等最简单的运算符都能像您期望的那样工作,但像变量语义这样的非平凡特性(在JLS的第 2 版和第 3 版中有所不同)呢?后者并不是您在JLS中可能发现的最重要的东西,尤其是在Java Memory Model中。volatile