虚拟机支持运行本地代码作为多重线程环境的一部分。当开发本地组件式有一些JNI技术的限制需要记住。
局部引用仅仅在这当前本地方法中有效和在执行本地方法的线程的上下文。本地引用在多个线程间不能被共享。仅仅全局引用能够被多个线程共享。
这个JNIEnv接口指针被传递给每个本地方法调用也是有效的,当这个线程和这个方法的调用相关联。它不能被缓存和由其它的线程使用。
synchronized(obj) {
/* Synchronized thread-safe code block. */
}
在本地的代码中,同样的水平的synchronization能够被存档使用JNI的监视方法。
if (JNI_OK == (*env)->MonitorEnter(env, obj)) {
/* Error handling. */
}
/* Synchronized thread-safe code block. */
if (JNI_OK == (*env)->MonitorExit(env, obj)) {
/* Error handling. */
}
Enter和Exit必须匹配,以防造成死锁。
本地的线程
因为本地的线程不被虚拟机知道,所有他们不能直接和Java的组件相互通信。本地的线程应该先附加到虚拟机上为了和存在的应用程序的部分通信。
Jni提供了AttachCurrentThread函数,通过JavaVm接口指针,运行本地代码附加本地线程到虚拟机上。这个JavaVm接口指针应该更早的缓存否则它不能获得。
JavaVM* cachedJvm;
...
JNIEnv* env;
...
/* Attach the current thread to virtual machine. */
(*cachedJvm)->AttachCurrentThread(cachedJvm, &env, NULL);
/* Thread can communicate with the Java application
using the JNIEnv interface. */
/* Detach the current thread from virtual machine. */
(*cachedJvm)->DetachCurrentThread(cachedJvm);