1、ThreadLocal的作用
ThreadLocal,即线程变量,ThreadLocal为变量在每个线程中都创建了一个副本,每个线程都可以通过set()和get()来对这个局部变量进行操作,但不会和其他线程的局部变量进行冲突,实现了线程的数据隔离。
Java内存模型的抽象结构示意图
2、ThreadLocalMap原理
ThreadLocalMap是ThreadLocal的一个静态内部类,里面定义了一个Entry来保存数据,而且还是继承的弱引用。在Entry内部key为当前ThreadLocal对象,value为ThreadLocal对象调用set方法设置的值。
ThreadLocalMap源码
ThreadLocalMap源码
从源码中看到 ThreadLocalMap 是一个 Map 结构,底层是数组,有初始化大小16,也有扩容阈值大小2/3。ThreadLocalMap 解决 hash 冲突的方式采用的是线性探测法,如果发生冲突会继续寻找下一个空的位置。
3、ThreadLocal内存泄漏
ThreadLocalMap的每个Entry都是一个对Key 的弱引用,每个Entry中都包含了一个对Value的强引用。
所以,如果ThreadLocal没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而value不会被清理掉。这样一来,ThreadLocalMap中就会出现key为null的Entry。假如我们不做任何措施的话,value永远无法被GC 回收,这个时候就可能会产生内存泄露。
解决方法:使用完ThreadLocal方法后 最好手动调用remove()方法清理掉 key 为 null 的记录。