47

我正在处理涉及大量并发编程的 Android 项目,并且我将实现一些自定义的线程间通信东西(来自java.util.concurent的那个不太适合我的目的)。

并发编程一般来说并不容易,但使用 Dalvik 似乎更难。要获得正确的代码,您应该知道一些具体的事情以及 Dalvik 出现问题的地方。我只是找不到有关 Dalvik VM 的详细文档。大多数 Android 资源(甚至developer.android.com都专注于平台 API,并且没有提供有关某些非平凡(或低级)事物的任何深入信息)。

例如,Dalvik VM 符合哪个版本的Java 语言规范?根据答案,volatile变量的处理是不同的,并且会影响使用volatile变量的任何并发代码。

已经有一些相关的问题:

fadden的一些答案非常有用,但我仍然想对相关问题进行更详细和完整的理解。

所以下面是我感兴趣的原始问题(如有必要,我将更新列表,因为之前问题的答案将会到来):

  1. 在哪里可以找到有关 Dalvik VM 的详细信息,可以为以下问题提供答案?
  2. Dalvik VM 符合哪个版本的Java 语言规范?
  3. 如果 (2) 的答案是“第三版”,那么 Dalvik 对本规范中所违反的Java 内存模型的支持如何完成?volatile尤其是对变量语义的支持如何完善?
  4. Android 中的双重检查锁定中fadden提供以下评论:

    是的。添加“volatile”关键字后,这将适用于单处理器(所有版本的 Android)和 SMP(3.0“honeycomb”及更高版本)

    这是否意味着具有双核 CPU 但只有 Android 2.3 的三星 Galaxy SII可能会错误地执行并发代码?(当然 Galaxy 只是一个例子,问题是关于任何具有 pre-Android 3.0 平台的多核设备)

  5. 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

4

4 回答 4

2

我还没有完全阅读你的问题,但首先不要使用 volatile,即使是 opengles 编码器也不会将它用于不同的 ui 和渲染器线程。

当且仅当一个线程写入(比如某个类的静态属性)和其他读取时才使用 volatile,即使那样你必须同步,阅读这个以获得一些处理计数的好方法

java - 如何在java中运行类的不同实例的线程之间同步静态变量?

  1. 总是使用同步
  2. 不要因为并发编程等困难主题而跳入大型项目
  3. 通过游戏中的 android 示例,他们讨论了可运行对象、处理程序和交换消息 b/w 线程(UI THREAD 和 RENDERER THREAD)的概念。
于 2012-08-03T03:48:03.967 回答
1

我想你回答了你自己的问题,虽然你没有详细说明为什么 java.util.concurrent 包不适合你的需求,但大多数移动应用程序只是使用异步 IO 和最少的线程。这些设备不是能够进行严重分布式处理的超级计算机,所以我有点难以理解为什么 java.util.concurrent 不能满足您的需求。

其次,如果您对 Dalvik 实现以及它是否符合 JLS(它不符合)有疑问,似乎可以推断,对线程机制的唯一可靠支持将是语言定义的那些 - java.util.concurrent, runnable和线程本地存储。

手动滚动内置语言支持之外的任何内容只会带来麻烦,并且正如您的问题所暗示的那样,Dalvik 可能不会以一致的方式支持。

与往常一样,当您认为自己可以比编写 Java 的人更好地执行线程时,请再想一想。

于 2012-07-29T10:30:30.430 回答
0

<从评论中复制> Dalvik 不符合任何 JLS 版本,因为符合性要求通过JCK,这不是 Dalvik 的选项。</复制自评论>

程序员真的应该知道在 Dalvik 上执行代码时他们可能依赖 JLS 的哪些功能

我认为他们知道的唯一方法是研究 Dalvik 测试套件(我打赌有一个,我希望它是开源的,不是吗?)。对于您需要的任何功能,1) 尝试查找如果您的功能实施不正确会失败的测试,并检查测试是否看起来足够好。如果没有这样的测试或不够好,1a) 添加新的或改进现有的测试。然后,2) 确定测试是否已针对您的目标实现成功运行。如果测试没有运行,那么 2a) 自己运行它,看看它是通过还是失败。

顺便说一句,上面大致是关于JCK的工作原理。主要区别在于,人们必须在 Dalvik 上投入自己的时间和精力,才能从 Sun/Oracle 获得理所当然的东西。另一个区别似乎是,对于 Dalvik,这没有记录,而Snorcle在该 iirc 上有明确的文档

但是文档中没有任何关于此的文字。

好吧,如果没有的话,那么我会说 Dalvik 文档的质量是次优的。轻声细语

于 2011-08-16T11:13:48.213 回答
0

这是诚实的答案。如果 java.util.concurrent 不能满足您的实现任务,那么您的问题不是 java.util.concurrent 而是您的原始设计规范。重新审视你的设计,也许在这里发布你的设计中使用简单互斥锁对你来说不合适的内容,然后社区可以向你展示如何更好地设计它。

于 2012-07-30T12:08:51.207 回答