个人更偏向于将其看做一个"工具类".为何这么说呢, 应为看似操作这个类,其实真实的"数据存放地"在各自对象的线程(Thread). 更多是,只是借用ThreadLocal这个类来检查,找到当前所在的线程.
下面会介绍如何和当前线程绑定,并放(set),如何取(get)数据:
1.问题
我们知道ThreadLocal为线程保存变量副本, 那这个ThreadLocal如何绑定的本线程呢?
2.线程下的"局部变量",这是核心,一切操作围着它展开
1).首先我们来看Thread中真实存放数据的地方.这里可见 数据 和 线程 是依存的关系.也正保证了 被线程独享.
public class Thread implements Runnable {
....
//剧透下,这里才是真正存储变量的位置,是和对应的线程绑定的
ThreadLocalMap threadLocals = null;
....
}
2). 我们来看下如何存取数据的,如何和当前线程建立绑定/联系的.
图一,是去Thread取局部变量threadLocals,未取到(第一次使用),为当前线程(set时会去获取当前Thread)进行创建threadLocals,并赋值过去。此后再去当前线程尝试获取就不会未null。
图二,是在图一运行过之后的流程。Thread.threadLocals!= null,则将变量值送入当前线程threadLocals保存。此后,此线程下的操作
可随时使用这个变量了。
图一
图二
get 操作也是首先获取当前线程的Thread.threadLocals,尝试去里面获取。
3.总结,我们可以看到
1)存放操作都要获取当前线程的引用(Thread.currentThread)
2)真正存储变量的是Thread.threadLocals,可以说ThreadLocal实现了和它的联系
3)所有如上操作都是借助ThreadLocal,乍想是个黑盒,是不是更像个工具类