ThreadLocal
1、ThreadLocal的作用
提供线程内部的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。
2、ThreadLocal的基本操作
2.1、构造函数
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517090914010-9577598.png)
ThreadLocal为空构造函数
2.2、initialValue函数
initialValue函数是用来设置ThreadLocal的初始值。
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517090939228-1425632476.png)
该函数是在get()的时候第一次调用,但是如果一开始就调用了set(),那么该函数不会被调用。通常该函数只会被调用一次,除非手动调用remove()之后在调用get(),这种情况下,还是会调用initialValue()。该函数是protected类型的,建议在子类中重载该函数,所以该函数都会以内部类的形式被重载,以指定初始值,比如:
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517091003369-1430960217.png)
2.3、get()
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517091421557-624379123.png)
看看get()的顺序:
1、获取当前线程
2、根据当前线程获取map
3、判断map是不是为空,如果不为空,则在map中以ThreadLocal的引用作为key获取map中的value。否则直接返回5;
4、如果e不为空,则返回e.value;否则返回5
5、通过initialValue()初始化一个value值,然后用ThreadLocal的引用和value创建一个新的map;
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517091447338-1876584390.png)
2.4、set()
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517091510619-567899885.png)
2.5、remove()
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517091537119-1480123208.png)
写个代码加深一下印象
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517091557025-652061300.png)
所以说各个线程之间是相互独立的。
再看一下ThreadLocal的内部类ThreadLocalMap
每个Thread维护一个ThreadLocalMap映射表,这个映射表的key是ThreadLocal实例本身,value是真正需要存储的Object。
getEntry()
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517091639135-208331018.png)
![](https://images2015.cnblogs.com/blog/808282/201705/808282-20170517091700916-41878516.png)
1、首先从ThreadLocal的直接索引位置i获取Entry e,如果e不为null并且key相同则返回e。
2、如果e为null或者key不一致则向下一个位置查询,如果下一个位置的key和当前需要查询的key相等,则返回对应的Entry,否则,如果key值为null,则删除该位置的Entry,否则继续向下一个位置查询。
在这个过程中遇到的key为null的Entry都会被删除,那么Entry内的value也就没有强引用链,自然会被回收。