您当前的位置: 首页 >  Java

命运之手

暂无认证

  • 2浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【NDK】【021】Java层回调方法ThreadId不断改变

命运之手 发布时间:2021-06-01 15:17:16 ,浏览量:2

判断线程的方法

安卓有两种区分线程的方法

一种是通过AndroidSDK自带的Process.myTid()方法来获取id

一种是通过JDK自带的Thread.currentThread().getId()方法来获取id

这两个id的命名规则是不同的,但都可以用来区分线程

JDK线程判断存在的隐患

AndroidSDK自带的Process.myTid()方法,获取到的是Linux系统底层线程的真正id

JDK的Thread.currentThread().getId()方法,只是JVM给自己的Thread对象定义的一个id

在纯Java开发中,JVM中的一个Thread就对应着Linux系统底层的一个线程

但是在NDK混合开发中就不是这样了,有可能出现JVM中的多个Thread工作在同一个Linux线程中的情况

请看以下JNI代码

	
	//JVM绑定Linux线程
	jvm->AttachCurrentThread(&jniEnv, 0);
	//JVM创建一个新的Thread,在当前Linux线程中执行VoidMethod
	jniEnv->CallVoidMethod(obj, onErrorMethod, code);
	//JVM解绑Linux线程
	jvm->DetachCurrentThread();
        

JVM每次执行VoidMethod方法,都会新建一个新的Thread对象,但是它们都工作在同一个Linux线程中

JVM中的Thread,只是Java对线程概念的一个理想化的抽象,Java希望它能在所有平台上能一致地工作。但实际实现却没有那么完美

Thread只是一个Java对象,Native代码的优先级是高于Java代码的,Native代码可以让JVM创建一个新的Thread对象,但仍然工作在当前Native线程中

而在纯Java开发环境中,由于没有Native代码,所有代码都调用JDK API,所有代码都运行在JVM中,则不会出现这种问题

开发建议

在纯Java开发环境中,使用两种方法判断线程是否相同,都是可以的

但在NDK开发中,尤其是Native代码经常回调Java代码时,建议使用Process.myTid()方法区分线程id

另外,Looper.getMainLooper().getThread().getId()本质上还是通过JDK的API来获取线程id的,也不建议使用

建议在Application.onCreate时,通过Process.myTid()方法来获取主线程pid,并保存到静态变量中

关注
打赏
1654938663
查看更多评论
立即登录/注册

微信扫码登录

0.0516s