JNI は、バックグラウンドで新しいスレッドを作成しません。ネイティブ関数は、ネイティブ関数を呼び出す Java メソッドと同じスレッドで実行されます。逆に、ネイティブ コードが Java メソッドを呼び出すと、Java メソッドは、メソッドを呼び出すネイティブ コードと同じスレッドで実行されます。
これには結果があります。ネイティブ関数が戻ると、ネイティブ関数呼び出しは Java コードに戻り、呼び出された Java メソッドが戻ると、ネイティブ コードは実行を継続します。
別のスレッドで実行する必要がある処理をネイティブ コードが実行する場合、スレッドを明示的に作成する必要があります。新しい Java スレッドを作成し、この専用スレッドからネイティブ メソッドを呼び出すことができます。または、ネイティブ コードで新しいネイティブ スレッドを作成し、それを開始して、ネイティブ関数から戻ることもできます。
// Call a native function in a dedicated java thread
native void cFunction();
...
new Thread() {
public void run() {
cFunction();
}
};
// Create a native thread - java part
native void cFunction()
...
cFunction();
// Create a native thread - C part
void *processing_function(void *p);
JNIEXPORT void JNICALL Java____cFunction(JNIEnv *e, jobject obj) {
pthread_t t;
pthread_create(&t, NULL, processing_function, NULL);
}
2 番目のバリアントを使用し、ネイティブに作成されたスレッドから Java コールバックを呼び出したい場合は、スレッドを JVM にアタッチする必要があります。どうやってするの?JNI アタッチ/デタッチ スレッドのメモリ管理を参照してください...