AttachCurrentThread卡在JNI中

时间:2019-03-25 01:20:54

标签: java multithreading java-native-interface

我试图了解JNI Application的奇怪行为。我正在从本机JNI dll例程(sayHello)启动线程,而该例程在启动时依次尝试附加到JVM线程以获取环境变量。但是,它暗示除非主线程退出,否则无法这样做。怎么来的?在下面的示例中(忽略线程内存泄漏),仅在主线程中的Thread.sleep(5000)之后,线程例程foo才能成功附加到JVM。这是为什么?

输出:

Hello World!!!
Hello World from C++!
Hello FROM FOO
Good Bye World!!!

 %%%     JNIEnv attached : 00000206FF8E7B40

JAVA代码

package com.home;

public class Main {

    static {
          System.loadLibrary("JNITest"); // Load native library hello.dll (Windows) or libhello.so (Unixes)
                                         //  at runtime
                                         // This library contains a native method called sayHello()
       }  

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub

        System.out.println("Hello World!!!");

        new Main().sayHello();

        Thread.sleep(5000);

        System.out.println("Good Bye World!!!");

    }

    // Declare an instance native method sayHello() which receives no parameter and returns void
    private native void sayHello();


}

JNI DLL

// JNITest.cpp : Defines the exported functions for the DLL application.
//
#include "com_home_Main.h"
#include "stdafx.h"
#include <iostream>
#include <thread> 

static JavaVM *g_jVM = NULL;

using namespace std;
void foo()
{
    JNIEnv *jEnv = NULL;

    cout << "Hello FROM FOO" << endl;

    g_jVM->AttachCurrentThreadAsDaemon((void **)(&jEnv), NULL);
    if (jEnv == NULL)
    {
        std::cout << "\n !!! Failed to attach current thread with JVM !!! \n";

    }
    else
    {
        std::cout << "\n %%%\t JNIEnv attached : " << (void *)jEnv;
        g_jVM->DetachCurrentThread();
    }
}



extern "C"
// Implementation of the native method sayHello()
JNIEXPORT void JNICALL Java_com_home_Main_sayHello(JNIEnv *env, jobject thisObj) {
    cout << "Hello World from C++!" << endl;

    env->GetJavaVM(&g_jVM);

    std::thread *first = new std::thread(foo);

    return;
}

0 个答案:

没有答案