java调用dll多线程,C ++多线程Java JNI方法调用

I have a simple class in Java:

public class MyClass

{

public static void dummyTest()

{

}

}

And in C++ I do the following JNI Call:

void c_call_function()

{

JNIEnv *env ...// the JNIEnv initialization in JNI...

jclass clazz ...// the class initialization in JNI...

jmethodID mid_dummyTest = env->GetStaticMethodID(clazz, "dummyTest", "()V");

env->CallStaticIntMethod(clazz, mid_dummyTest);

}

If a single program calls the static method c_call_function() it is ok.

But if a multithread program calls the c_call_function(), it gives me the following message, when passes the line env->CallStaticIntMethod(clazz, mid_dummyTest);:

Access violation at 0x000000006FC77154 read to 0x0000000000000000

If the program is multithread, it uses the same JNIEnv variable.

But I also tried to load the same JNIEnv via AttachCurrentThread method and it gives me the same problem.

What is the restriction when calling the method bellow by multiple threads as long as I don't create any local references or even delete or modify anything?

env->CallStaticIntMethod(clazz, mid_dummyTest);

解决方案

I a able to run similar code (look below) where I have multiple threads accessing the same JVM (macOS). I am using pthread.

Few things that are important

attaching thread to JVM ("The JNI interface pointer (JNIEnv) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread() to attach itself to the VM and obtain a JNI interface pointer.")

joining threads

i guess it's a good idea to use mutex as well to prevent multiple threads being attached

main.c

#include

#include

#include

#define NUM_THREADS 6

pthread_mutex_t mutexjvm;

pthread_t threads[NUM_THREADS];

struct JVM {

JNIEnv *env;

JavaVM *jvm;

};

void invoke_class(JNIEnv* env);

void *jvmThreads(void* myJvm) {

struct JVM *myJvmPtr = (struct JVM*) myJvm;

JavaVM *jvmPtr = myJvmPtr -> jvm;

JNIEnv *env = myJvmPtr -> env;

pthread_mutex_lock (&mutexjvm);

printf("I will call JVM\n");

(*jvmPtr)->AttachCurrentThread(jvmPtr, (void**) &(env), NULL);

invoke_class( env );

(*jvmPtr)->DetachCurrentThread(jvmPtr);

pthread_mutex_unlock (&mutexjvm);

pthread_exit(NULL);

}

JNIEnv* create_vm(struct JVM *jvm)

{

JNIEnv* env;

JavaVMInitArgs vm_args;

JavaVMOption options;

options.optionString = "-Djava.class.path=./";

vm_args.options = &options;

vm_args.ignoreUnrecognized = 0;

vm_args.version = JNI_VERSION_1_6;

vm_args.nOptions = 1;

int status = JNI_CreateJavaVM(&jvm->jvm, (void**)&env, &vm_args);

if (status < 0 || !env)

printf("Error\n");

return env;

}

void invoke_class(JNIEnv* env)

{

jclass Main_class;

jmethodID fun_id;

Main_class = (*env)->FindClass(env, "Main");

fun_id = (*env)->GetStaticMethodID(env, Main_class, "fun", "()I");

(*env)->CallStaticIntMethod(env, Main_class, fun_id);

}

int main(int argc, char **argv)

{

struct JVM myJvm;

myJvm.env = create_vm(&myJvm);

if(myJvm.env == NULL)

return 1;

pthread_mutex_init(&mutexjvm, NULL);

for(int i=0; i

pthread_create(&threads[i], NULL, jvmThreads, (void*) &myJvm);

pthread_join(threads[i], 0);

}

(*myJvm.jvm)->DestroyJavaVM(myJvm.jvm);

}

Main.java

public class Main {

public static void main(String[] args){

System.out.println("Hello, world");

}

public static int fun() {

System.out.println("From JVM");

return 0;

}

}

Makefile

all: Main.class main

Main.class: Main.java

javac Main.java

main.o: main.c

llvm-gcc -c main.c \

-I${JAVA_HOME}/include \

-I${JAVA_HOME}/include/darwin/ \

main: main.o

ld -o main -L${JAVA_HOME}/jre/lib/server/ \

-ljvm \

-rpath ${JAVA_HOME}/jre/lib/server \

-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk \

-demangle -dynamic -arch x86_64 \

-macosx_version_min 10.12.0 \

-lSystem \

-rpath ${JAVA_HOME}/jre/lib/server/ \

main.o

clean:

rm -f Main.class main main.o

Once you run the code, you get following result:

./main

I will call JVM

From JVM

I will call JVM

From JVM

I will call JVM

From JVM

I will call JVM

From JVM

I will call JVM

From JVM

I will call JVM

From JVM

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值