1

A と B の 2 つのネイティブ スレッドがあるとします。スレッドでは、AI は JNI メソッドを使用して Java メソッド (コンストラクター、静的メソッドなど) を呼び出して Java オブジェクトを取得し、それへのグローバル参照を取得します。

java_vm->AttachCurrentThread(&env,NULL);
j_ref_inputStream = env->CallObjectMethod(g_j_ref_btSocket,j_mid_getInputStream);
g_j_ref_inputStream = env->NewGlobalRef(j_ref_inputStream);

ここで、グローバル参照をスレッド B に渡し、そこでメソッドを呼び出します。

java_vm->AttachCurrentThread(&env2,NULL);
jint b = env2->CallIntMethod(g_j_ref_inputStream,j_mid_read);

InputStream で read() を呼び出すと、スレッド B がブロックされます (そうですか?)。スレッド BI を強制的にブロック解除するには、IOException の生成を試みることができます。したがって、スレッド AI では次のようにします。

env->callVoidMethod(g_j_ref_btSocket,j_mid_close);

しかし、どこでこの例外をキャッチできますか? JNI とネイティブ スレッドについてはよくわかりません。スレッド A で次のように呼び出しますか。

j_exception = env->ExceptionOccurred();
if(j_exception) // handle exception

またはスレッド B で:

j_exception = env2->ExceptionOccurred();
if(j_exception) // handle exception

それとも関係ありませんか?(どちらの場合も理由を詳しく教えてください)

4

1 に答える 1

0

JNI の側面は忘れてください。自分が何をしようとしているのかを考えてみてください。役立つ場合は、純粋なJavaで考えてください。読み取りがブロックされているストリームを閉じて、スレッド B のブロックを解除しようとしています。したがって、B は例外を取得します。

実際には、例外を「期待」しているスレッドだけでなく、すべての JNI 呼び出しの後に、両方のスレッドが「ExceptionOccurred()」を呼び出す必要があります。ただし、スレッド B はこの例外を受け取ります。

于 2013-10-02T23:52:44.337 に答える