JNI - AttachCurrentThread

•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、付费专栏及课程。

余额充值