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对象。