简谈Thread Local工作原理
-
什么是Thread Local?
Thread Local 是一个线程内部的数据存储类,每一个线程都维护一个table[],通过set(),get()方法实现存取操作。
只能在指定的线程中获取存储的数据,其他的线程一般无法获取。(注意:这里我用的是一般,可以使用InheritableThreadLocal达到其他线程获取数据的)
-
什么情况下使用Thread Local呢?
一般来说,当某些数据以线程为作用域并且不同线程具有不同的数据副本时,就考虑用它了
典型的例子是:Handler要获取当前线程的Looper,Looper的作用域为线程,每个线程具有不同的Looper.
Thread Local的使用方法
private void testThreadLocal() {
new Thread(new Runnable() {
//创建ThreadLocal 对象,支持泛型
ThreadLocal<String> mLocal = new ThreadLocal<String>();
@Override
public void run() {
mLocal.set("Fan Bin Bin is nice!");
String s = mLocal.get();
Log.i("TAG", s);
}
}).start();
}
打印结果:
threadlocaltest I/TAG: Fan Bin Bin is nice!
有一个特殊的例子可以实现不同线程的访问存储变量
private void testThreadLocal() {
final ThreadLocal<String> local = new InheritableThreadLocal<>();
local.set("I love China");
new Thread(new Runnable() {
@Override
public void run() {
Log.i("TAG", local.get() + "");
}
}).start();
}
打印结果:
com.yutianwang.threadlocaltest I/TAG: I love China
这里在主线程中创建了InheritableThreadLocal对象,居然在子线程中能够打印出这句话,实现原理大致是:当子线程创建的时候,主线程会将InheritableThreadLocal对象传递给子线程中去,所以能够打印这句话。
LocalValues内部有个数组:private Object[] table,Thread local的值就存储在这个table数组中
取出当前线程LocalValues对象,如果为null,返回初始值,如果不为空,从table数组中取出Thread Local值
总结
Thread Local所做的读写操作仅限于各自线程的内部,所以在多个线程中互补干扰的存储和修改数据。
声明
此文是建立在《Android开发艺术探索》和
http://droidyue.com/blog/2016/03/13/learning-threadlocal-in-java/
这篇文章基础上的读书笔记。(PS:准大三狗真是累!hh)