java - Android java+原生数据可见性

标签 java android multithreading

假设我的游戏应用程序中有两个线程(除了主线程):

  • GLRenderer 线程(由 Android 的 GLSurfaceView.Renderer 提供)
  • 另一个线程(游戏线程)

两个线程都使用 JNI 调用应用程序的某些 C++(即 Android NDK)组件。

假设我在 Java 中分配了一个直接的 IntBuffer(例如,从 GLRenderer 线程,但不要这样假设)。事实:

  • 这个直接缓冲区由来自 GLRenderer 线程的 native 代码读取(即由通过 JNI 调用的 C++ 组件)
  • 这个直接缓冲区有时是从其他线程(游戏线程)写入

在以下两种情况下,什么是(最佳)同步方式(实际上是确保数据可见性),即保证 GLRenderer 代码中的 native 代码看到最新的 IntBuffer 内容?

  • 场景 #1:游戏线程的 Java 代码写入 IntBuffer(例如通过 IntBuffer.put())
  • 场景 #2:从游戏线程调用的 native 代码写入 IntBuffer

我认为标准的 Java 同步对这两种情况都适用:

public void onDrawFrame(GL10 gl) { // the GLRenderer thread
    // ...
    synchronized (obj) {
        callNativeCode1(); // a JNI call; this is where the C++ native code reads the IntBuffer
    }

}

public void run() { // the game thread
    // ...

    synchronized (obj) {
        intBuffer.put(...); // writing the buffer from managed code
    }

    // ...
    synchronized (obj) {
        callNativeCode2(); // a JNI call; writing the buffer from C++ native code
    }
}

最佳答案

不知道与 JNI 共享内存的细节,但我建议使用 AtomicIntegerArray

您的选择是:

  1. synchronized - 您需要以某种方式在 JNI 中实现相同的功能 - 并不容易。
  2. volatile - 使整个数组 volatile 将是一个问题。
  3. atomics - 我会说最好的路线。

参见 Package java.util.concurrent.atomic对于:

The AtomicIntegerArray, AtomicLongArray, and AtomicReferenceArray classes further extend atomic operation support to arrays of these types. These classes are also notable in providing volatile access semantics for their array elements, which is not supported for ordinary arrays.

这基本上可以确保只要 JNI 代码不做任何事情来绕过 Java 的缓存刷新语义,那么 JNI 包应该看到一个一致的和更新的数据 View 。

我会推荐一些重要的研究来证实这一点,但我相信这是您实现目标的唯一途径。

关于java - Android java+原生数据可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19536137/

相关文章:

java - 如何从 flatMap 创建 HashMap?

android - 非法状态异常 : view has already been added to the window manager

python - Pandas、Concurrent.Futures 和 GIL

android - Android 中的重新加载 Activity

c++ - 最接近 `std::atomic<std::vector>` 的是什么?

java - 如何在一个线程处于 sleep 模式时实现多线程

java - 在 Java 中更新 MySQL 表

java - 热点循环条件优化器的奇怪行为

c# - 有没有一个可以复制 Java 代码并粘贴为 C# 代码的插件?

android - 防止用户在 Android 上终止应用程序