我的云文档怎么没有了(我的云文档怎么找)
823
2022-05-29
java中要访问C++代码时, 使用JNI是唯一选择. 然而,在多线程的情况下, 可能出现以下问题:
问题描述:
一个java对象通过JNI调用DLL中一个send()函数向服务器发送消息,不等服务器消息到来就立即返回.同时
把JNI接口的指针JNIEnv *env,和jobject obj保存在DLL中的变量里.
一段时间后,DLL中的消息接收线程接收到服务器发来的消息,
并试图通过保存过的env和obj来调用先前的java对象的方法来处理此消息.
然而,JNI文档上说,JNI接口的指针JNIEnv*不能在c++的线程间共享,
在我的程序中,如果接收线程试图调用java对象的方法,程序会突然退出.
不知道有没有方法突破JNI接口的指针不能在多个c++线程中共享的限制?
解决办法:
在 http://java.sun.com/docs/books/jni/html/pitfalls.html#29161 提到,
JNI接口指针不可为多个线程共用,但是java虚拟机的JavaVM指针是整个jvm公用的. 于是,在DLL中可以调用:
static JavaVM* gs_jvm;
env->GetJavaVM(&gs_jvm); //来获取JavaVM指针.获取了这个指针后,在DLL中的另一个线程里,可以调用:
JNIEnv *env;
gs_jvm->AttachCurrentThread((void **)&env, NULL);
(1)
//java代码:Test.java:
import java.io.*;
class Test implements Runnable
{
public int value = 0;
private Thread tx=null;
public Test()
{
tx=new Thread(this,"tx");
}
static
{
System.loadLibrary("Test");
}
public native void setEnev();
public static void main(String args[])
{
Test t = new Test();
t.setEnev();
System.out.println("ok in java main");
t.tx.start();
try
{
Thread.sleep(10000000);
}catch(Exception e)
{
System.out.println("error in main");
}
}
public void run()
{
try
{
while(true)
{
Thread.sleep(1000);
System.out.println(value);
}
}catch(Exception e)
{
System.out.println("error in run");
}
}
}
(2)
//DLL代码:Test.cpp:
#include "test.h"
#include
#include
static JavaVM *gs_jvm=NULL;
static jobject gs_object=NULL;
static int gs_i=10;
void WINAPI ThreadFun(PVOID argv)
{
JNIEnv *env;
gs_jvm->AttachCurrentThread((void **)&env, NULL);
jclass cls = env->GetObjectClass(gs_object);
jfieldID fieldPtr = env->GetFieldID(cls,"value","I");
while(1)
{
Sleep(100);
//在DLL中改变外面的java对象的value变量的值.
env->SetIntField(gs_object,fieldPtr,(jint)gs_i++);
}
}
JNIEXPORT void JNICALL Java_Test_setEnev(JNIEnv *env, jobject obj)
{
printf("come into test.dll/n");
//Returns “0” on success; returns a negative value on failure.
int retGvm=env->GetJavaVM(&gs_jvm);
//直接保存obj到DLL中的全局变量是不行的,应该调用以下函数:
gs_object=env->NewGlobalRef(obj);
HANDLE ht=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFun,0,NULL,NULL);
printf("the Handle ht is:%d/n",ht);
}
C++ Java 任务调度
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。