ThreadLocal 如何实现数据的线程隔离?
ThreadLocal
本身其实并不维护存储数据的Map
或者Entry
,ThreadLocal
只是提供了操作数据的功能。最终存储数据的结构是ThreadLocalMap
中的Entry
。
Thread
中维护了对ThreadLocal
中的ThreadLocalMap
进行维护。一个线程维护一个ThreadLocalMap
,Entry
的Key
维护操作的ThreadLocal
实例。一个线程一份,实现数据隔离。
ThreadLocal 导致内存泄漏问题?
ThreadLocal
+ 线程池 导致内存泄漏:
ThreadLocal
配合线程池的场景下使用很有可能导致内存泄漏,进而导致OOM
。
如果当ThreadLocal
对象在使用完之后,应该要把设置的Key
,Value
,也就是Entry
对象进行设置null
,使得GC
能够正常回收。
但是由于线程池中的线程不会进行回收,线程对象中的threadLocals
属性是通过强引用指向ThreadLocalMap
,ThreadLocalMap
通过强引用指向Entry
对象,线程池中的Thread
对象不会回收,导致Entry
对象也不会被回收,从而出现内存泄漏。
解决方案:
在使用完ThreadLocal
对象之后,手动调用remove
方法,清除Entry
对象。