一、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。
4、使用场景
NamedThreadLocal:RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder、SimpleDateFormat等的共享应用
网友评论