并发编程----ThreadLocal

一、ThreadLocal

1、作用:使用ThreadLocal来做线程级的缓存,因为各个线程使用ThreadLocal中的数据是互不影响的,不存在数据安全的问题。

2、初始化步骤

1)在ThreadLocalMap中定位到ThreadLocal为key的entry项;

2)  如果存在entry项,同时存在key,则直接用新的value替换掉旧的value;

3)如果存在entry项,同时key为空,那么就恢复key的值和重新设置value;

4)如果不存在entry,则创建一个新的entry项。

需要说明的是,在进行set操作时,当ThreadLocal被设置为null时,ThreadLocalMap就会移除key为ThreadLocal的Entry(因为Entry本身就是一个弱引用对象)。

3、ThreadLocal内存泄漏的原因

 可以看出,ThreadLocalMap中的key是弱引用类型。Java进行垃圾回收时,会一直回收掉弱引用类型的对象。在代码实例中,key即ThreadLocal对象是弱引用类型,当没有强引用指向ThreadLocal对象时,gc会回收掉Entry中的key,即回收ThreadLocal对象本身。而value不会被回收掉的,因为value是强引用。Entry对象是位于ThreadLocal对象内的,既然ThreadLocal对象已经被回收掉了,entry就成了一个引用不可达的对象,gc无法回收,所以会出现内存泄露。

为了避免这个问题,可以先调用ThreadLocal的remove的方法,以便清除掉不需要的value。

参考深入分析ThreadLocal内存泄漏

4、使用场景

NamedThreadLocal:RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder、SimpleDateFormat等的共享应用

你可能感兴趣的:(并发编程----ThreadLocal)