JNI - AttachCurrentThread

本文详细介绍了Java Native Interface (JNI) 中本地线程如何通过AttachCurrentThread()和DetachCurrentThread()方法与Java虚拟机交互,并提供了Java和C代码示例展示如何在子线程中调用Java方法。

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

•The JNI interface pointer(JNIEnv) isvalid only in the current thread.
•Should another thread need to access theJava VM, it must first call AttachCurrentThread() toattach itself to the VM and obtain a JNI interface pointer.
•Once attached to the VM, a native threadworks just like anordinary Java thread running inside a native method.
•The native thread remains attached to theVM until it calls DetachCurrentThread()todetach itself.

Java:

import java.lang.management.ManagementFactory; 
class MyThread{
	private static void fromJNI(int i){
		System.out.print("Java---------->");
		System.out.println(i);
	}

	public static void main(String args[]){
		MyThread mt = new MyThread();
		mt.setJNIEnv();
		mt.mainThread();
		
	}

	//native methods
	private native void mainThread();
	private native void setJNIEnv();

	static{
		//First, we use java.lang.management.ManagementFactory to show the pid of java progress.
		String name = ManagementFactory.getRuntimeMXBean().getName();  
		System.out.println("Progress id in Java \n\t"+name);  		
		System.loadLibrary("MyThread");
	}

}

C:

#include <jni.h>
#include "MyThread.h"
#include <iostream>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>

using namespace std;


#define NUMTHREADS 5

JavaVM *g_jvm = NULL;
jobject g_obj = NULL;
int sum=0;

void *thread_fun(void* arg)
{
    long tid;
    tid = (long) arg; 
    cout<<"Execute order="<<sum++<<endl;
    cout<<"thread id="<<tid<<endl;

    JNIEnv *env;
    jclass cls;
    jmethodID mid;
    //Attach主线程

    if(g_jvm->AttachCurrentThread((void**)&env, NULL) != JNI_OK)
    {
        printf("%s: AttachCurrentThread() failed", __FUNCTION__);
        return NULL;
    }

    //找到对应的类
    cls = env->GetObjectClass(g_obj);
    if(cls == NULL)
    {
        printf("FindClass() Error.....");
        goto error;
    }
    //再获得类中的方法
    mid = env->GetStaticMethodID( cls, "fromJNI", "(I)V");
    if (mid == NULL)
    {
        printf("GetMethodID() Error.....");
        goto error; 
    }
    //最后调用java中的静态方法
    env->CallStaticVoidMethod(cls, mid ,(int)tid);
  
error:   
    //Detach主线程
    if(g_jvm->DetachCurrentThread() != JNI_OK)
    {
        printf("%s: DetachCurrentThread() failed", __FUNCTION__);
    }

     sleep(30);
     pthread_exit(0);

}





//Second
//由java调用以创建子线程
JNIEXPORT void JNICALL Java_MyThread_mainThread
  (JNIEnv *env, jobject obj){
    int i;
    pthread_t pt[NUMTHREADS];
    for (i = 0; i < NUMTHREADS; i++){
	//创建子线程
        //pthread_create(&pt[i], NULL, &thread_fun, (void*)i);
    }
    //Because the main thread exits. Put a sleep in the main thread.
    //Or no result will be shown.
    sleep(30);
/*
	you can also try to use join
*/
}


//First
//由java调用来建立JNI环境
JNIEXPORT void JNICALL Java_MyThread_setJNIEnv
  (JNIEnv *env, jobject obj){
   //保存全局JVM以便在子线程中使用
    env->GetJavaVM(&g_jvm);
    //不能直接赋值(g_obj = obj)
    g_obj = env->NewGlobalRef(obj);
    

}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值