Dalvik VM& Java内存模型(Android上的并发编程)

时间:2011-08-07 15:18:36

标签: android concurrency dalvik java-memory-model

我正在研究涉及大量并发编程的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)的回答是“第三版”,那么Dalviks对 Java内存模型的支持在本规范中是否完备?尤其是对volatile变量的语义支持有多完整?
  4. Double checked locking in Android fadden 中提供以下评论:

      

    烨。通过添加“volatile”关键字,这将适用于单处理器(所有Android版本)和SMP(3.0“蜂窝”及更高版本)

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

  5. Is Dalvik's memory model the same as Java's? fadden 中,使用以下句子提供答案:

      

    目前没有发布的Dalvik版本与JSR-133

    完全正确

    这是否意味着任何现有的正确并发Java代码在发布此评论的任何Android版本上可能无法正常工作?

  6. 更新#1:回答@ gnat的评论(太长时间无法评论)

    @gnat发表评论:

      

    @Alexey Dalvik不符合任何JLS版本,因为一致性要求通过JCK,这不是Dalvik的选项。 这是否意味着您甚至无法应用标准Java编译器,因为它符合标准规范?是否重要?如果有,怎么样?

    好吧,我的问题有点含糊不清。我实际上的意思是 JLS 不仅是Java编译器实现的规则,而且是任何 JVM 实现的隐式指南。实际上,例如, JLS 表明某些类型的读写是原子操作。编译器编写器不是很有趣,因为读/写只是转换成单个操作码。但是对于任何 JVM 实现来说,正确实现这些操作码是必不可少的。现在你应该看看我在说什么。虽然Dalvik接受并执行使用标准Java编译器编译的程序,但 没有任何保证 表明它们已正确执行 (正如您所料),因为没有人(Dalvik的开发人员除外)知道Dalvik是否支持该程序中使用的所有JLS功能。

    很明显 JCK 不是Dalvik的选项而且没关系,但是程序员真的应该知道 JLS 功能他们可能会在Dalvik上执行代码时依赖它们。但是在文档中没有任何关于此的话。虽然您可能期望像=,+, - ,*等这样的最简单的运算符可以正常工作,因为您需要关于非平凡的功能,如volatile变量的语义(这是不同的第二版和第三版 JLS )?后者不是你在 JLS 中找到的最重要的东西,尤其是 Java Memory Model

4 个答案:

答案 0 :(得分:2)

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

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

How to synchronize a static variable among threads running different instances of a class in java?

  1. 始终使用synchronize
  2. 不要针对像并发编程这样的困难主题跳过大型项目
  3. 在他们讨论过runnables概念的游戏中浏览android示例, 处理程序,并交换消息b / w线程(UI线程和RENDERER线程)。

答案 1 :(得分:1)

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

其次,如果你对Dalvik实现有疑问,以及它是否符合JLS(它没有),那么似乎有理由认为对线程机制唯一可靠的支持是语言定义的那些 - java.util。并发,可运行和线程本地存储。

在内置语言支持之外滚动任何东西只会引发麻烦,正如您的问题所暗示的那样,Dalvik可能无法以一致的方式支持。

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

答案 2 :(得分:0)

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

  

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

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

以上BTW大致是关于 JCK 的工作原理。主要区别在于,必须为Dalvik投入自己的时间和精力,因为从Sun / Oracle获得的东西是理所当然的。另一个差异似乎是对于Dalvik而言,没有记录,而 Snorcle 在该iirc上有明确的文档

  

但在文档中没有任何关于此的话。

如果没有任何言论,那么我会说Dalvik文档的质量不是最理想的。轻声说话

答案 3 :(得分:0)

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