news 2026/10/5 12:36:03

JNI 编程指南12—— JNI多线程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JNI 编程指南12—— JNI多线程

目录

  • 核心要点
  • 示例程序

JNI多线程

核心要点

JNI 环境下,进行多线程编程,有以下两点是需明确的:

  • JNIEnv 是一个线程作用域的变量,不能跨线程传递,每个线程都有自己的 JNIEnv 且彼此独立
  • 局部引用不能在本地函数中跨函数使用,不能跨线程使用,当然也不能直接缓存起来使用

示例程序

示例程序主要演示:

如何在子线程获取到属于子线程自己的 JNIEnv
上面说了局部引用不能再线程之间直接传递,所以我们只有另觅他法
Java 层:

publicvoidjavaCallback(intcount){Log.e(TAG,"onNativeCallBack : "+count);}publicnativevoidthreadTest();

Native 层:

staticintcount=0;JavaVM*gJavaVM=NULL;//全局 JavaVM 变量jobject gJavaObj=NULL;//全局 Jobject 变量jmethodID nativeCallback=NULL;//全局的方法ID//这里通过标志位来确定 两个线程的工作都完成了再执行 DeleteGlobalRef//当然也可以通过加锁实现bool main_finished=false;bool background_finished=false;staticvoid*native_thread_exec(void*arg){LOGE(TAG,"nativeThreadExec");LOGE(TAG,"The pthread id : %d\n",pthread_self());JNIEnv*env;//从全局的JavaVM中获取到环境变量gJavaVM->AttachCurrentThread(&env,NULL);//线程循环for(inti=0;i<5;i++){usleep(2);//跨线程回调Java层函数env->CallVoidMethod(gJavaObj,nativeCallback,count++);}gJavaVM->DetachCurrentThread();background_finished=true;if(main_finished&&background_finished){env->DeleteGlobalRef(gJavaObj);LOGE(TAG,"全局引用在子线程销毁");}return((void*)0);}extern"C"JNIEXPORTvoidJNICALLJava_com_yuandaima_myjnidemo_MainActivity_threadTest(JNIEnv*env,jobject thiz){//创建全局引用,方便其他函数或线程使用gJavaObj=env->NewGlobalRef(thiz);jclass clazz=env->GetObjectClass(thiz);nativeCallback=env->GetMethodID(clazz,"javaCallback","(I)V");//保存全局 JavaVM,注意 JavaVM 不是 JNI 引用类型env->GetJavaVM(&gJavaVM);pthread_tid;if(pthread_create(&id,NULL,native_thread_exec,NULL)!=0){return;}for(inti=0;i<5;i++){usleep(20);//跨线程回调Java层函数env->CallVoidMethod(gJavaObj,nativeCallback,count++);}main_finished=true;if(main_finished&&background_finished&&!env->IsSameObject(gJavaObj,NULL)){env->DeleteGlobalRef(gJavaObj);LOGE(TAG,"全局引用在主线程销毁");}}

示例代码中,我们的子线程需要使用主线程中的jobject thiz,该变量是一个局部引用,不能赋值给一个全局变量然后跨线程跨函数使用,我们通过NewGlobalRef将局部引用装换为全局引用并保存在全局变量jobject gJavaObj中,在使用完成后我们需要使用DeleteGlobalRef来释放全局引用,因为多个线程执行顺序的不确定性,我们使用了标志位来确保两个线程所有的工作完成后再执行释放操作。

JNIEnv 是一个线程作用域的变量,不能跨线程传递,每个线程都有自己的 JNIEnv 且彼此独立,实际开发中,我们通过以下代码:在子线程中获取到 JNIEnv。

JavaVM*gJavaVM=NULL;//主线程获取到 JavaVMenv->GetJavaVM(&gJavaVM);//子线程通过 JavaVM 获取到自己的 JNIEnvJNIEnv*env;gJavaVM->AttachCurrentThread(&env,NULL);

JavaVM 是一个普通指针,由 JVM 来管理其内存的分配与回收,不是 JNI 引用类型,所以 我们可以把它赋值给一个全局变量,直接用,也不用考虑他的内存分配与后续问题。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 13:31:52

2026年EOR名义雇主服务TOP5精选,助力企业快速实现全球拓展

EOR名义雇主为企业提供灵活的解决方案&#xff0c;助力其在全球市场快速扩张。这种服务可以帮助企业应对复杂的法律法规&#xff0c;确保合规雇佣。这是因为EOR名义雇主承担了员工的法律责任&#xff0c;同时企业依然可以掌控业务运营。通过利用顶尖的服务商&#xff0c;企业能…

作者头像 李华
网站建设 2026/10/4 20:27:45

主流iPaaS平台解析:破解企业系统集成难题的关键路径

数字化转型步入深水区&#xff0c;企业正遭遇愈发棘手的集成难题&#xff1a;新旧系统交织、多云环境共生、数据孤岛凸显、业务流程断裂。iPaaS&#xff08;集成平台即服务&#xff09;凭借云原生、敏捷化、低代码的核心优势&#xff0c;成为企业搭建统一数字连接体系、助推业务…

作者头像 李华
网站建设 2026/10/4 21:31:52

Java毕设选题推荐:基于SpringBoot+Vue的模拟证券交易软件平台的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/10/4 20:27:17

django+Python微信小程序的高校实验室管理系统设计与实现

文章目录 摘要关键词 系统设计与实现的思路主要技术与实现手段源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 摘要 该系统基于Django框架和Python语言开发&#xff0c;结合微信小程序平台&#xff0c;设计并实现了一套高校实验室管理系…

作者头像 李华
网站建设 2026/10/4 18:54:02

【课程设计/毕业设计】基于SpringBoot的心灵治愈交流平台心理健康交流系统的设计与实现【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/10/5 11:39:47

开题报告卡壳?虎贲等考 AI:3 步解锁 “导师一眼认可” 的学术框架

开题报告是学术研究的 “第一块敲门砖”&#xff0c;却成了无数学生的 “毕业拦路虎”&#xff1a;选题要么太旧缺乏创新&#xff0c;要么太泛难以落地&#xff1b;文献综述堆砌观点毫无逻辑&#xff0c;研究方案写得模糊不清&#xff1b;甚至连 “研究意义”“技术路线” 的格…

作者头像 李华