Search code examples
androidconcurrencyjava-native-interface

Android Multi Threading with native code


I am working on an android project and found that an operation becomes bottleneck in performance. This operation works on a large array A and stores the result into another array B.

I found that this operation can be parallelized. The array A can be divided into N smaller segments. The operation can work on each segment independently and store the result into a corresponding segment in B.

The operation is written in native code with GetPrimitiveArrayCritical/ReleasePrimitiveArrayCritical pairs to access array A and B.

My question is that if using multi threading, GetPrimitiveArrayCritical(pEnv, A, 0) will be called multiple times from different threads. Does GetPrimitiveArrayCritical block? i.e. if one thread makes this call, can a second thread make the same call before the first one calls ReleasePrimitiveArrayCritical()?

Please help.


Solution

  • Yes, you can call GetPrimitiveArrayCritical() from two concurrent threads. The function will not block, and your two threads will grant access to the underlying array to native code. But on the other hand, the function will do nothing to synchronize this access, i.e. if thread 1 changes the value at index 100, and thread 2 also changes the value at index 100, you don't know which will be chosen at the end.

    If you don't write to the array, you are guaranteed to be served correctly. Don't forget to ReleasePrimitiveArrayCritical with JNI_ABORT flag.

    If you want to write to the array, check the output parameter isCopy as set by GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy). If the result is 0, you can safely proceed with your multithreaded approach.

    If the result is not 0, ReleasePrimitiveArrayCritical() will overwrite all elements of the Java array, even if some of them was changed in Java or in C on a different thread. If your program detects this situation, it must release the array (with JNI_ABORT) and wait for the other thread to complete. On Android I have never seen an array being copied, they are always locked in-place. But nobody will guarantee that this will not happen to you, either in a current system or in a future version.

    That's why you MUST check isCopy parameter.