线程本地变量,每个线程都有自己的本地变量,用来保证线程安全
底层原理
底层维护了一个ThreadLocalMap 数组
内存溢出的原因
ThreadLocal的原理是操作Thread内部的一个ThreadLocalMap,这个Map的Entry继承了WeakReference,设值完成后map中是(WeakReference,value)这样的数据结构。java中的弱引用在内存不足的时候会被回收掉,回收之后变成(null,value)的形式,key被收回掉了。
如果线程执行完之后销毁,value也会被回收,这样也没问题。但如果是在线程池中,线程执行完后不被回收,而是返回线程池中,Thread有个强引用指向ThreadLocalMap,ThreadLocalMap有强引用指向Entry,导致value无法被回收,一直存在内存中。在执行了ThreadLocal.set()方法之后一定要记得使用ThreadLocal.remove(),将不要的数据移除掉,避免内存泄漏。通过分析源码,java也做了一定优化,即使出现了上诉的(null,value)情况,再调用一次ThreadLocal.set()也可以将这个废弃的替代调用
解决方案
每次使用完都remove
其他问题
初始化,需要设值,否则会报NPM