我有一个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();
}
答案 0 :(得分:0)
是的,正确的方法是使用DirectByteBuffer
。但它有自己的缺点。例如,此类Buffer不受数组支持,从Java端访问它可能效率较低。