带本机代码的Android多线程

带本机代码的Android多线程,android,concurrency,java-native-interface,Android,Concurrency,Java Native Interface,我正在从事一个android项目,发现一个操作会成为性能的瓶颈。此操作适用于大型阵列a,并将结果存储到另一个阵列B中 我发现这个操作可以并行化。阵列A可分为N个较小的段。该操作可以独立处理每个段,并将结果存储到B中的相应段中 该操作使用本机代码编写,使用GetPrimitiveArrayCritical/ReleasePrimitiveArrayCritical对访问数组A和B 我的问题是,如果使用多线程,GetPrimitiveArrayCritical(pEnv,A,0)将从不同的线程被多次

我正在从事一个android项目,发现一个操作会成为性能的瓶颈。此操作适用于大型阵列a,并将结果存储到另一个阵列B中

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

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

我的问题是,如果使用多线程,GetPrimitiveArrayCritical(pEnv,A,0)将从不同的线程被多次调用。GetPrimitiveArrayCritical块吗?i、 e.如果一个线程进行此调用,第二个线程能否在第一个线程调用ReleasePrimitiveArrayCritical()之前进行相同的调用


请提供帮助。

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

如果不向数组写入,则可以保证正确地为您提供服务。不要忘记使用
JNI\u ABORT
标志
ReleasePrimitiveArrayCritical

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

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


这就是为什么您必须检查
isCopy
参数。

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

如果不向数组写入,则可以保证正确地为您提供服务。不要忘记使用
JNI\u ABORT
标志
ReleasePrimitiveArrayCritical

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

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


这就是为什么您必须检查
isCopy
参数。

嗨,Alex,我有点困惑。在第二段中,您提到ReleasePrimitiveArrayCritical()将覆盖Java数组的所有元素,即使其中一些元素被另一个线程更改。如果是这种情况,那么使用GetPrimitiveArrayCritical+ReleasePrimitiveArrayCritical的多线程处理对我的问题不起作用。然后您说GetPrimitiveArrayCritical()总是将数组锁定到位。你能告诉我在哪里可以找到更多关于这个的文档吗?谢谢。对不起,我的解释让人困惑。我试图详细说明,请参阅更新的answer.FWIW,在开发人员设备上,您可以配置JNI,以便它总是尽可能复制数据。这是为了帮助跟踪某些类型的错误。forcecopy模式还将保护区域置于缓冲区前后,并在缓冲区释放时进行检查。看。@fadden:酷,这是一个重要的验证工具。这无助于了解客户设备的性能状况。嗨,Alex,我有点困惑。在第二段中,您提到ReleasePrimitiveArrayCritical()将覆盖Java数组的所有元素,即使其中一些元素被另一个线程更改。如果是这种情况,那么使用GetPrimitiveArrayCritical+ReleasePrimitiveArrayCritical的多线程处理对我的问题不起作用。然后您说GetPrimitiveArrayCritical()总是将数组锁定到位。你能告诉我在哪里可以找到更多关于这个的文档吗?谢谢。对不起,我的解释让人困惑。我试图详细说明,请参阅更新的answer.FWIW,在开发人员设备上,您可以配置JNI,以便它总是尽可能复制数据。这是为了帮助跟踪某些类型的错误。forcecopy模式还将保护区域置于缓冲区前后,并在缓冲区释放时进行检查。看。@fadden:酷,这是一个重要的验证工具。这无助于了解客户设备上的性能状况。