类结构
ThreadLocal包含两个静态内部类
SuppliedThreadLocal extends ThreadLocal
ThreadLocalMap
SuppliedThreadLocal
是ThreadLocal
的子类,增强了初始化的功能,带有一个初始化的值
ThreadLocalMap
是一个自定义的哈希映射HashMap
,仅适用于维护线程局部值.没有操作导出到ThreadLocal类之外.该类是包私有的,以允许声明Thread类中的字段. 为了帮助处理非常长的使用寿命,哈希表条目使用WeakReferences
作为键. 但是,由于未使用引用队列,因此仅在表开始空间不足时,才保证删除过时的条目
方法结构
ThreadLocal
ThreadLocal
T是一个泛型,他可以是任意Object
ThradLocal#get()
返回此线程局部变量的当前线程副本中的值;如果该变量没有当前线程的值,则首先将其初始化为调用ThreadLocal#initialValue()
返回的值
ThreadLocal#set()
将此线程局部变量的当前线程副本设置为指定值;大多数子类将不需要重写此方法,而仅依靠ThreadLoal#initialValue()
方法来设置线程局部变量的值
ThreadLocal#remove()
删除此线程局部变量的当前线程值. 如果此线程局部变量随后被当前线程ThreadLocal#get()
调用, 则其值将通过调用其ThreadLocal#initialValue()
方法来重新初始化, 除非当前值是ThreadLocal#set()
在此期间父类穿行 这可能会导致在当前线程中多次调用ThreadLocal#initialValue()
方法
ThreadLocal#remove()
移除应用什么情况下才会出现内存泄露?
如图, 在某一线程内, 在方法内 new ThreadLocal() 局部变量 出来, 那么当线程执行完, 栈桢回收, 方法局部变量被回收, 那么当前线程的ThreadLocalMap的 这个ThreadLocal对象已经被回收, 弱引用key变为null, 但是他的值并没有被回收, 也不会被定义为垃圾, 所以只要当前线程没被销毁,这个值的对象就一直不被释放, 如果这种情况的线程大量存在, 那内存泄露就很严重了.
如何解决内存泄露的问题?
只要在方法执行完成后执行remove()方法/get()方法即可
为什么?
remove()会把当前方法内的ThreadLocal对应的value的object置为null
这样value值的object应用就会被定义为垃圾,最终被垃圾收集器回收
如何优雅的解决?
使用同一接口封装ThreadLocal对象,让其执行完方法统一调用公共方法将其null->value的值置为null
https://mp.weixin.qq.com/s/JwRT6QzNU8FojbCgGg-8QQ