4-07 初次接触ThreadLocal必看

4-07 初次接触ThreadLocal必看

ThreadLocal结构

类结构

ThreadLocal包含两个静态内部类

  • SuppliedThreadLocal extends ThreadLocal
  • ThreadLocalMap

SuppliedThreadLocalThreadLocal的子类,增强了初始化的功能,带有一个初始化的值
ThreadLocalMap是一个自定义的哈希映射HashMap,仅适用于维护线程局部值.没有操作导出到ThreadLocal类之外.该类是包私有的,以允许声明Thread类中的字段. 为了帮助处理非常长的使用寿命,哈希表条目使用WeakReferences作为键. 但是,由于未使用引用队列,因此仅在表开始空间不足时,才保证删除过时的条目

方法结构

ThreadLocal

  • get()
  • set()
  • remove()

ThreadLocal T是一个泛型,他可以是任意Object

ThradLocal#get() 返回此线程局部变量的当前线程副本中的值;如果该变量没有当前线程的值,则首先将其初始化为调用ThreadLocal#initialValue()返回的值

ThreadLocal#set() 将此线程局部变量的当前线程副本设置为指定值;大多数子类将不需要重写此方法,而仅依靠ThreadLoal#initialValue()方法来设置线程局部变量的值

ThreadLocal#remove()删除此线程局部变量的当前线程值. 如果此线程局部变量随后被当前线程ThreadLocal#get()调用, 则其值将通过调用其ThreadLocal#initialValue()方法来重新初始化, 除非当前值是ThreadLocal#set()在此期间父类穿行 这可能会导致在当前线程中多次调用ThreadLocal#initialValue()方法

ThreadLocal用法

  • 主动设置线程内共享变量,或者使用默认初始化值
  • 使用完成后/线程销毁前, ThreadLocal#remove()移除应用

ThreadLocal问题

内存泄露

什么情况下才会出现内存泄露?

4-07 初次接触ThreadLocal必看_第1张图片

如图, 在某一线程内, 在方法内 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

你可能感兴趣的:(4-07 初次接触ThreadLocal必看)