一、ThreadLocal结构
一个Thread中存在字段为ThreadLocalMap
ThreadLocal.ThreadLocalMap threadLocals = null;
也就是说我们使用threadLocal进行set操作和get操作,其实就是操作该Thread的threadLocalMap。
这个map是一个基于数组的key和value的格式,在进行get的时候,会将调用对象this作为key进行查询。
二、ThreadLocalMap解决下标冲突
hashMap是通过链表法,threadLocalMap是通过开放寻址法,也就是通过key进行求余下标得到元素,判断是否全等,如果是则返回,如果不是,则再次寻址,也就是下标+1,继续判断是否全等,直到找到。
三、ThreadLocal内存溢出问题
在ThreadLocalMap中的Entry对象的key是弱引用。
这样能保证在线程结束的时候,可以将key进行回收。
但是如果线程一直没有结束,那么就会导致threadLocal的key和value一直绑定到thread中,但是又没有用到这个对象。
- 线程一直执行
- 大量的threadLocal对象
- 对应的threadLocal对象的value过大
那么为什么会存在线程一直执行呢? 那就是线程池,核心线程数会一直开启,并且如果核心线程在使用前里的threadLocals也应该清空。
四、总结
在使用threadLocal之后,需要使用remove进行移除即可。