JNI缓存java数组

时间:2015-04-30 14:13:01

标签: java c++ arrays java-native-interface

我有一个java应用程序和一些本机c ++代码。 java应用程序运行一些线程。每个线程都有一个double数组,它作为参数传递给本机代码。到目前为止一切运作良好。现在在我的本机代码中,我想在数组中写入值。目前我正在这样做:

  JNIEXPORT void JNICALL Java_JNIPerformanceTest_alterArray___3I_3D
    (JNIEnv *env, jobject, jintArray intArray, jdoubleArray doubleArray){

         jint count = env->GetArrayLength(doubleArray);
         jdouble* S_native = env->GetDoubleArrayElements(doubleArray, NULL);

         for (int i=0; i < count; i++) {
                S_native[i] = i;
         }

         jint count2 = env->GetArrayLength(intArray);
         jint* S_native2 = env->GetIntArrayElements(intArray, NULL);


         for (int i=0; i < count2; i++) {
                S_native2[i] = i;
         }

         env->ReleaseDoubleArrayElements(doubleArray, S_native, 0);
         env->ReleaseIntArrayElements(intArray, S_native2, 0);
    }

由于GetArrayLength和GetDoubleArrayElements需要一些时间而且我总是将相同的java数组实例传递给本机代码,我想知道是否有一个解决方案没有获取元素指针并释放函数调用。我已经尝试在全局存储指针,当然还有

 env->NewWeakGlobalRef(array);

。但是,如果我不在此数组上调用ReleaseDoubleArrayElements,则在java中检查时元素不会更改。 解决这样一个问题的最佳方法是什么?使用ByteBuffer?

这也是我的java代码:

    double ARRAY_SIZE = 10;

    for (int i = 0; i < 4; i++) {
        Thread thread = new Thread(new Runnable() {

            boolean done = false;

            @Override
            public void run() {
                while (true) {
                    double d[] = null;
                    int intArray[] = null;
                    if (!done) {
                        d = new double[ARRAY_SIZE];
                        for (int i = 0; i < ARRAY_SIZE; i++) {
                            d[i] = 222;
                        }

                        intArray = new int[ARRAY_SIZE];
                    }

                    long start = System.nanoTime();
                    alterArray(intArray, d);

                    long end = System.nanoTime();
                    System.out.println("test_alterArray: time for " + NUM_LOOPS + " loops: " + ((end - start) / 1000) + " us.");

                }
            }
        });
        thread.start();
    }

1 个答案:

答案 0 :(得分:0)

是的,正确的方法是使用DirectByteBuffer。但它有自己的缺点。例如,此类Buffer不受数组支持,从Java端访问它可能效率较低。