Android多线程与本机代码

时间:2013-05-31 18:04:08

标签: android concurrency java-native-interface

我正在研究一个Android项目,发现操作成为性能瓶颈。此操作适用于大型数组A,并将结果存储到另一个数组B中。

我发现这个操作可以并行化。阵列A可以分成N个较小的段。该操作可以独立地处理每个段,并将结果存储在B中的相应段中。

该操作使用GetPrimitiveArrayCritical / ReleasePrimitiveArrayCritical对以本机代码编写,以访问数组A和B.

我的问题是,如果使用多线程,将从不同的线程多次调用GetPrimitiveArrayCritical(pEnv,A,0)。 GetPrimitiveArrayCritical是否阻止?即如果一个线程进行此调用,第二个线程可以在第一个线程调用ReleasePrimitiveArrayCritical()之前进行相同的调用吗?

请帮忙。

1 个答案:

答案 0 :(得分:1)

是的,您可以从两个并发线程中调用GetPrimitiveArrayCritical()。该函数不会阻塞,您的两个线程将授予对本机代码的底层数组的访问权限。但另一方面,函数将无法同步此访问,即如果线程1更改索引100处的值,并且线程2也更改索引100处的值,则您不知道最后会选择哪个值

如果您不写入数组,则可以保证您正确使用。不要忘记带有ReleasePrimitiveArrayCritical旗帜的JNI_ABORT

如果要写入数组,请检查GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)设置的输出参数isCopy。如果结果为0,则可以安全地继续使用多线程方法。

如果结果不为0,ReleasePrimitiveArrayCritical()将覆盖Java数组的所有元素,即使其中一些元素在Java中更改或在另一个线程上的C中更改。如果您的程序检测到这种情况,它必须释放该数组(使用JNI_ABORT)并等待另一个线程完成。 在Android上我从未见过要复制的数组,它们总是被锁定到位。 但是没有人会保证在当前系统或未来版本中不会发生这种情况。

这就是你必须检查isCopy参数的原因。

相关问题