当前位置: 首页 > 面试题库 >

JNI-多线程

盛辰沛
2023-03-14
问题内容

我有一个从C调用的Java函数的JNI包装器。我试图从不同的线程调用某些方法,并且在尝试获取JNIEnv指针的新副本时收到错误消息。下面使用m并在每种方法中调用它:

        JNIEnv* GetJniEnvHandle(){
        ThreadInfo();
        JNIEnv *envLoc; 
        //if(Thread::CurrentThread->IsBackground || Thread::CurrentThread->IsThreadPoolThread)  
        jint envRes = vm->GetEnv((void**)&envLoc, JNI_VERSION_1_4);
        if(envRes == JNI_OK){
            if(ThreadId != Thread::CurrentThread->ManagedThreadId)
                jint res = vm->AttachCurrentThread((void**)&envLoc, NULL);
        }else{          
            Log("Error obtaining JNIEnv* handle");  
        }
        return envLoc;
    }

从主线程/初始线程调用JVM时,该JVM已被实例化,并且该(和其他方法)运行。当我获得envRes的值时,在子线程中它保持-2。


问题答案:

请参阅本章的文档Attaching to the VM

AttachCurrentThread()在使用任何JNI函数之前,您至少需要为每个本机线程调用一次。
用Java创建的线程已附加。
因此,我以您的示例为例,无论何时GetEnv呼叫失败AttachCurrentThread(),您都应该没事。或确保在创建子线程时将其附加到VM。



 类似资料:
  • 我有一个Android应用程序,它由一些本机线程(未连接到JVM)组成,需要能够调用Java对象的方法。 我打算这样做的方式是创建一个JNI函数,我从相关的Java对象调用它,它允许我在静态本机数据结构中获取和缓存所需的java对象方法ID、JNIEnv和对象引用,以便我的本机线程可以(线程安全地)访问所需的方法(例如,使用(*env)- 我不相信这种方法会起作用,因为我读到JNIEnv指针不能在

  • 问题内容: 我有一个JNI回调: 当我像这样(空有用的代码)运行它时,会发生内存泄漏。如果我注释掉整个方法,则不会泄漏。连接/分离线程的正确方法是什么? 我的应用程序处理实时声音数据,因此负责数据处理的线程必须尽快完成,以便为下一批做好准备。因此,对于这些回调,我创建了新线程。每秒有数十个甚至数百个它们,它们将自己附加到JVM,调用一个回调函数来重绘图形,分离并消亡。这是做这些事情的正确方法吗?如

  • Android的JNI提示页面提到了这个常见问题:为什么FindClass没有找到我的类?他们提到了多种解决方案,最后一种选择是: 将对ClassLoader对象的引用缓存在方便的地方,并直接发出loadClass调用。这需要一些努力。 所以,我试着让它工作,似乎不管怎样,这种方法根本不适合我。最后,我想出了如何使用类加载器,但如果从本机线程中尝试加载尚未接触/加载的类,它将不起作用。本质上,它与

  • 我试图决定JNI是否适合我们的用例。 我们有一个用C编写的库,它使用多个线程从数据库/RPC获取数据,我们希望创建一个包装器,让Java代码能够调用它。 我不熟悉JNI,所以我想知道在这种情况下C多线程是否仍能正常工作。 谢谢

  • 问题内容: 我正在使用此处接受的答案中的方法来构造一个gameloop线程。 AndroidService类中的哪里停止/销毁线程? 此刻,我的线程基本上获取了时间,进行了一个本机功能调用,以更新游戏逻辑,然后在调整的经过时间之前进入睡眠状态。 令我好奇的是,由于我对Threads仍然不太满意,因此用interrupt()杀死Thread有多快?如果它在本机函数中运行的代码的中间,它将停止在其中,

  • 在android中,我使用pthread_create来创建一个本地线程,然后在回调过程中,调用FindClass来获取一个Java类。但是它不起作用。我从android jni提示中获得提示,我从Android JNI中的任何线程中找到了FindClass中的解决方案 我为我的项目修改它,如下[编辑] 程序在env退出- 如果我删除