admin管理员组文章数量:1612066
关键总结
1、android.os.Process.myTid返回的是操作系统级别的线程实例的线程号,在JNI开发过程我们一般称之为natvie线程的线程号
2、Thread.currentThread.getId返回的是JVM级别的线程实例对应的线程号(一个递增的Id),JVM线别的线程称之为Java线程
3、一个native线程当前只能绑定一个Java线程,但可以多次绑定线程实例,这个绑定线程实例过程其实是发生在我们的创建的native线程将要跟Java代码做交互时前的的attchJVM的操作,如果每次都交互前后都做attach与deattch的操作,会导致natvie线程不断的绑定到JVM线程是不同的。这种情况你在回调的Java代码中调用android.os.Process.myTid与Thread.currentThread.getId的返回值就会是不一样的了
代码示例
// 这个方法多个native线程会调用到,
public void log(int level, final String msg) {
int tid = android.os.Process.myTid();
Thread thread = Thread.currentThread();
long tid2 = thread.getId();
Log.i("test", String.format("android.os.Process.myTid = %d, getId = %d, thread = " +
"%s, thread hashCode = %d", tid, tid2,
thread.toString(), thread.hashCode()));
}
如上图所示,26128是Natvie线程的线程号,会频繁的回调Java的方法,然后JNI的交互策略是—每次都调AttachCurrentThread方法,然后调用Java的方法后就DetachCurrentThread。所以你会看到它每次绑定的线程都是新的,从线程号可以看出来
Java ThreadLocal
在如上case的情况下,如果native回调到Java方法中就不能再用ThreadLocal实例的get方法了,因为每次都是一个新的Java线程,每次都会new一份ThreadLocal容器中的实例,就背离了使用ThreadLocal的初衷!ThreadLocal缓存线程的线程数据的Key是Java的线程实例(可以看下Threadlocal的get方法的源码),C++ std中也有ThreadLocal,那才真实跟系统线程相关的线程存储数据
示例代码如下
private static final String DATE_FORMAT = "HH:mm:ss.SSS";
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<>();
private static DateFormat getDateFormat() {
DateFormat df = threadLocal.get();
if (df == null) {
df = new SimpleDateFormat(DATE_FORMAT);
Log.i("test", "new SimpleDateFormat");
threadLocal.set(df);
}
return df;
}
private static String formatDate(Date date) {
String result = "";
try {
result = getDateFormat().format(date);
} catch (Exception e) {
}
return result;
}
public void log(int level, final String msg) {
int tid = android.os.Process.myTid();
Thread thread = Thread.currentThread();
long tid2 = thread.getId();
Log.i("test", String.format("android.os.Process.myTid = %d, getId = %d, thread = " +
"%s, thread hashCode = %d", tid, tid2,
thread.toString(), thread.hashCode()));
formatDate(new Date());
}
关键代码
myTid
/**
* See <a href="http://man7/linux/man-pages/man2/gettid.2.html">gettid(2)</a>.
*/
public static int gettid() { return Libcore.os.gettid(); }
ThreadLocal.get
/**
* Returns the value in the current thread's copy of this
* thread-local variable. If the variable has no value for the
* current thread, it is first initialized to the value returned
* by an invocation of the {@link #initialValue} method.
*
* @return the current thread's value of this thread-local
*/
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
参考资料
- JAVA THREAD LOCAL到底存储在哪里
版权声明:本文标题:android.os.Process.myTid与Thread.currentThread.getId的区别 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1728627328a1166661.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论