java线程 jni_C多线程Java JNI方法调用

本文展示了如何在C程序中使用JNI调用Java方法,并通过多线程安全地操作同一JVM。主要步骤包括线程附加、连接、使用互斥体保护JVM访问,以及线程分离。示例代码创建了6个线程,每个线程都会调用Java类的静态方法,输出'From JVM'。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我能够运行类似的代码(如下所示),其中有多个线程访问同一JVM(macOS).我正在使用pthread.

很少有重要的事情

>将线程附加到JVM(根据文档,一次只能有一个线程可以使用JVM)

>连接螺纹

>我想也最好使用互斥体以防止连接多个线程

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

");

(*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

");

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;

}

}

生成文件

all: Main.class main

Main.class: Main.java

javac Main.java

main.o: main.c

llvm-gcc -c main.c \n -I${JAVA_HOME}/include \n -I${JAVA_HOME}/include/darwin/ \n

main: main.o

ld -o main -L${JAVA_HOME}/jre/lib/server/ \n -ljvm \n -rpath ${JAVA_HOME}/jre/lib/server \n -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk \n -demangle -dynamic -arch x86_64 \n -macosx_version_min 10.12.0 \n -lSystem \n -rpath ${JAVA_HOME}/jre/lib/server/ \n 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值