判断线程的方法
安卓有两种区分线程的方法
一种是通过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,并保存到静态变量中