【并发专题】threadLocal 连环炮
本问题对应的项目链接:高频题回答模版训练
PS:这个的话,问的也不多,但是有时候在项目中会用到这个东西,如果你在项目中写上了,那么碰到懂的面试官,还是会问
1、介绍一下 threadLocal,简单说一下他的使用场景?
2、ThreadLocal的key是哪种引用类型?为啥这么设计?
3、ThreadLocal 是怎么防止内存泄漏?
本问题对应的项目链接:高频题回答模版训练
PS:这个的话,问的也不多,但是有时候在项目中会用到这个东西,如果你在项目中写上了,那么碰到懂的面试官,还是会问
1、介绍一下 threadLocal,简单说一下他的使用场景?
2、ThreadLocal的key是哪种引用类型?为啥这么设计?
3、ThreadLocal 是怎么防止内存泄漏?
共以下 1 个回答
1、介绍一下 threadLocal,简单说一下他的使用场景?
ThreadLocal 用于提供线程的局部变量,在多线程环境可以保证各个线程里的变量独立于其它线程,是一个以 ThreadLocal 对象为键,任意对象为值的存储结构。底层是通过一个 ThreadLocalMap 来存储和管理的。
它可以用于多线程处理多任务的场景,每个线程使用 ThreadLocal 单独保存自己的任务上下文,然后执行计算。
2、ThreadLocal 的 key 是哪种引用类型?为啥这么设计?
弱引用。这样设计是为了防止某些情况下 ThreadLocal 可能会导致的内存泄漏。
3、ThreadLocal 是怎么防止内存泄漏?
简单来说是「弱引用」加「手动调用 remove( ) 」方法。
因为 ThreadLocalMap 主要有一个 Entry 数组,每一个 Entry 是继承了 ThreadLocal 类型的弱引用,并将其作为 key。value 是 Entry 中的一个 Object 成员变量。那么我们在创建 ThreadLocal 变量时,每一个 ThreadLocal 对象就有两个引用,一个是堆栈对它的强引用,一个是 ThreadLocalMap 中的 Entry 对它的弱引用。
现在假设 Entry 是对 ThreadLocal 的强引用而不是弱引用,在将 ThreadLocal 置空后,堆栈上的 ThreadLocal 强引用就会消失,但 Entry 对它的强引用还在,无法被回收,并且 Entry 的 value 值也是个强引用,也无法被回收,这就导致了内存泄漏。
将 Entry 继承自 ThreadLocal 的弱引用可以解决 ThreadLocal 的回收问题,但还是无法解决 value 的回收问题。ThreadLocal 在设计时就考虑到了这个问题,并且有一些防护措施:在调用 ThreadLocal 的 get( ),set( ) 和 remove( ) 的时候都会清除当前线程 ThreadLocalMap 中所有 key 为 null 的 value。所以在使用 ThreadLocal 的时候,每次用完都最好调用一下 remove( ) 方法,来防止内存泄漏。
4、demo
value 内存泄漏示例:
正常示例演示: