ThreadLocal知多少

ThreadLocal要解决的根本问题是实现线程隔离
  • 共享变量本地化
ThreadLocal 如何实现变量本地化

根本在于搞清楚 Thread和ThreadLocal、ThreadLocalMap 三者之间的关系

ThreadLocal的get()方法可以一窥究竟

请添加图片描述

  • Thread 持有 ThreadLocalMap ,意思就是讲每个线程本地都会有一个ThreadLocalMap

  • 而这个ThreadLocalMap 的key 就是ThreadLocal对象

  • 这样的话,每个线程持有相同的Key去各自的Map中查询相应的value,不就实现了线程之间的隔离吗

    我们可以举个例子

  • 有两个线程、3个ThreadLocal

ThreadLocal<String> threadLocal1 =  new ThreadLocal<>();
ThreadLocal<Integer> threadLocal2 =  new ThreadLocal<>();
ThreadLocal<Integer> threadLocal3 =  new ThreadLocal<>();

Thread 、threadLocalMap、ThreadLocal 三者的关系如图:

请添加图片描述

通过上面的分析基本上已经搞清楚ThreadLocal到底是个什么东东了,我们不妨再了解一下ThreadLocalMap这个内部类

看到ThreadLocalMap,我们不由的会想起HashMap,有些相似,但又有不同,我们来看下ThreadLocalMap的两个核心方法 getEntry()和set()

getEntry()

请添加图片描述

根据注释、应该已经很清楚了

set()

请添加图片描述

ThreadLocal内存泄露之弱引用的问题

什么被弱引用了,看源码
请添加图片描述

可以肯定的一点是ThreadlocalMap的生命周期是和线程保持一致,那么问题的关键就来了,我们一般使用线程都是使用线程池,那线程基本上是不会呗清理掉的呢,那不就容易内存泄露了吗
怎么办呢?
请添加图片描述

上图中,我们可以弱引用的只有Entry的Key了 这样发生GC的时候ThreadLocalMap中的key就可以被回收

我们在看源码的时候,发现好多地方都有这个个判断k==null,则清理。,因为k已经被回收了,value也米有意义了,所以会被清理。

至此ThreadLocal该明白的都明白了吧?

完结,散花!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值