ThreadLocal - 包含 静态ThreadLocalMap内部类 (这里map不是指的jdk中的Map结构,只是名字这么取)
ThreadLocalMap 又包含静态 Entry 内部类
ThreadLocalMap 中定义了Entry[]数组
Thread中 定义了 ThreadLocal.ThreadLocalMap threadLocals 属性。
要使用ThreadLocal
先定义一个ThreadLocal对象。 ThreadLocal被定义出来就是被用来做key的
然后将ThreadLocal对象作为Entry的key属性,value为自定义的对象(即线程本地需要存储的内容)
然后将Entry放入Thread的 threadLocals 属性中
从代码操作上来说如下
在当前线程下 ThreadLocal对象 . set(“xxx”); ,即在线程的threadLocals中的Entry[] 中加了以ThreadLocal对象为key的Entry
获取则是在当前线程下ThreadLocal对象.get() ,内部代码会根据key反向的找出 set的对象
这样就实现了线程本地私有对象,该对象只能在本线程下设置及读取
同时还有一个问题
ThreadLocal对象在线程theadLocals中被强引用指向的话,
即使包含ThreadLocal对象的方法已经结束,但线程还活着,会导致无法通过ThreadLocal对象获取值,同时该对象无法被GC回收,操作内存泄漏。
所以在Entry中是使用弱引用指向ThreadLocal对象。
这样方法结束时,原有的声明强引用被回收,ThreadLocal对象无法获取到,同时此时也没有强/软引用指向它,也会被GC回收。
但是Entry中的value是强引用,key为null的Entry还存在于线程内,所以只能是在调用线程的操作本地变量的方法时,检索有没有key为null,这时候删掉这个Entry
我们一般定义ThreadLocal是静态的,是希望其就是全局的,此时就会一直有强引用指向,上面回收的问题也就没有这个操作。
这套回收流程的存在,是为了ThreadLocal为局部的,局部方法结束是对用的线程内ThreadLocal的Entry的回收