多线程JNI调用
Multithreaded JNI-Calls
我了解到,每次使用JNIEnv
时,都必须使用jvm->AttachCurrentThread
将c线程附加到jvm。这应该非常类似于互斥锁,我在方法的开始用jvm->AttachCurrentThread
锁定它,在方法的结束用jvm->DetachCurrentThread()
解锁它。所以,现在我有了一种方法,可以更频繁地使用JNIEnv
。我每次都要打AttachCurrentThread
吗?这里有一个代码示例:
std::unique_ptr<IState> JNIGame::createEmptyState() {
JNIEnv* env;
jvm->AttachCurrentThread((void**)&env, NULL);
if(!jGame_createEmptyState)
jGame_createEmptyState = env->GetMethodID(jGameC, "createEmptyState", "()Ljni/JNIGames$IJNIState;");
JNIState *state = new JNIState();
//needed?
jvm->AttachCurrentThread((void**)&env, NULL);
state->jStateO = env->CallObjectMethod(jGameO, jGame_createEmptyState);
jvm->DetachCurrentThread();
return std::unique_ptr<IState>(state);
}
正如您所看到的,我附加了两次线程,因为如果没有第二次,代码就会崩溃。但如果它们的行为像互斥锁,那么只需要第一个。你能帮我吗?为什么我每次都需要它们?它像现在的代码一样保存吗?
不确定你所说的"像互斥体一样行动"是什么意思,但文档中说,"试图附加一个已经附加的线程是不可能的。"
您的示例附加两次,然后分离一次。第二次附加无效。
我引用的这句话来自JNI文档的"调用API"一章。"调用API"是他们对需要从C调用Java的收集方法的调用(而不是用于编写可以从Java调用的本机方法的方法)
有几点值得一提:
启动JVM的线程是隐式附加的。该线程成为JVM的"主"线程。
只要最后一个非守护进程线程退出,JVM就会关闭(无法重新启动)。如果本机线程分离,则被视为线程退出。
我的应用程序有一个专用的"主"线程,它启动JVM,通知其他线程它已经启动,然后永远休眠。当我的应用程序的其他本机线程都没有使用休眠的"主"线程时,它使我的JVM保持活力。
AttachCurrentThread
允许添加您在JVM外部创建的线程,以便添加到Java虚拟机中。它不打算被称为"每次使用JNIEnv
时",也绝不是"类似于互斥体"。
此外,引用文件:
尝试附加已附加的线程是不可行的。
如果您的代码崩溃,可能是因为AttachCurrentThread
是而不是互斥。如果方法JNIGame::createEmptyState()
由多个线程调用,则必须使用真正的互斥。
通常,在与虚拟机交互时,您会连接一个线程一次,并将其连接更长的时间,而不是在每个方法之后将其分离。
- JNI从Android调用C++方法
- JNI 在应用程序中检测到错误:在为 innerclass 调用 NewObject 时使用了无效的 jobject
- 从C++调用dll实现的JNI
- 如何在JNI中从线程内部调用JAVA方法
- Android JNI RegisterNatives:对所有内容调用一次,或者每个函数调用一次
- 如何使用JNI从Android本机C++调用PackageManager.hasSystemFeature?
- 如何调用传递给 JNI 'jobject' 的 Java 对象的子类/子类的方法
- Java 1.8 本机 System.load 通过 JNI 调用C++产生 TLSv1.如何获取 TLSv1.2?
- 无法使用 JNI 从C++模块成功调用 Java 函数
- Android 无法从本机代码调用 Java 方法 JNI
- 从 JNI 调用的 DLL 从哪里获取其内存以进行分配,例如 Malloc
- 如何从 NDK(JNI) 调用特定的 Java 方法
- C 多线程JAVA JNI方法调用
- JNI GetMethodID 调用,带有挂起的异常 java.lang.ClassNotFoundException
- Android JNI:Java通过JNI调用C++类对象
- 从 Android JNI/NDK 代码中的C++函数调用 C 函数
- 如何从 JNI 传递 std::list 参数来调用本机 C++ 函数
- 直接从C++调用 JNI c++ 方法是不可能的
- 当从c++调用JNI Java方法时,它会被丢弃
- 从动态库调用jni时,JVM堆内存不足