首页 / JAVA / C多线程Java JNI方法调用
C多线程Java JNI方法调用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C多线程Java JNI方法调用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3404字,纯文字阅读大概需要5分钟。
内容图文
![C多线程Java JNI方法调用](/upload/InfoBanner/zyjiaocheng/685/661f7c52c9124bce8f063bbb6682e0d3.jpg)
我在Java中有一个简单的类:
public class MyClass
{
public static void dummyTest()
{
}
}
然后在C中执行以下JNI调用:
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);
}
如果单个程序调用静态方法c_call_function()可以.
但是,如果多线程程序调用c_call_function(),则在通过env-> CallStaticIntMethod(clazz,mid_dummyTest);行时会给我以下消息:
访问冲突在0x000000006FC77154读取为0x0000000000000000
如果程序是多线程,则使用相同的JNIEnv变量.
但是我也尝试通过AttachCurrentThread方法加载相同的JNIEnv,这给了我同样的问题.
只要我不创建任何本地引用,甚至不删除或修改任何内容,当由多个线程调用以下方法时,会有什么限制?
env->CallStaticIntMethod(clazz, mid_dummyTest);
解决方法:
我能够运行类似的代码(如下所示),其中有多个线程访问同一JVM(macOS).我正在使用pthread.
很少有重要的事情
>将线程附加到JVM(根据文档,一次只能有一个线程可以使用JVM)
>连接螺纹
>我想也最好使用互斥体以防止连接多个线程
main.c
#include <stdio.h>
#include <jni.h>
#include <pthread.h>
#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<NUM_THREADS; 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;
}
}
生成文件
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
运行代码后,将得到以下结果:
./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
内容总结
以上是互联网集市为您收集整理的C多线程Java JNI方法调用全部内容,希望文章能够帮你解决C多线程Java JNI方法调用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。