ThreadLocal底层原理

一:什么是ThreadLocal

ThreadLocal是一个创建线程局部变量的类,ThreadLocal中的变量只有当前自身线程可以访问,别的线程都访问不了。

实现原理:
每一个线程都有一个对应的Thread对象,而Thread类有一个ThreadLocalMap类型变量(threadLocals)和一个内部类ThreadLocal。这个threadLocals的key就是ThreadLocal的引用,而value就是当前线程在key所对应的ThreadLocal中存储的值。当某个线程需要获取存储在自己线程Thread的ThreadLocal变量中的值时,ThreadLocal底层会获取当前线程的Thread对象中的Map集合threadLocals,然后以ThreadLocal作为key,从threadLocals中查找value值。这就是ThreadLocal实现线程独立的原理。
在这里插入图片描述
为什么用Entry数组而不是Entry对象?
因为在业务代码中能new好多个ThreadLocal对象,各司其职。但是在一次请求里,也就是一个线程里,ThreadLocalMap是同一个,而不是多个。不管你new几次ThreadLocal,ThreadLocalMap在一个线程里就一个,因为ThreadLocalMap的引用是在Thread里的。所以它里面的Entry数组存放的是一个线程里你new出来的多个ThreadLocal对象。

二:理解ThreadLocal中的内存泄漏问题

ThreadLocal.ThreadLocalMap是一个比较特殊的Map,它的每个Entry的key都是一个弱引用。
这样设计的好处是,如果这个变量不再被其他对象使用时,可以自动回收这个ThreadLocal对象,避免可能的内存泄露。

注意:Entry中的value,依然是强引用。
在这里插入图片描述
ThreadLocalMap中的key是弱引用,当不存在外部强引用的时候,就会自动被回收。但是Entry中的value依然是强引用。这个value的引用链条如下:
在这里插入图片描述
可以看到,只有当Thread被回收时,这个value才有被回收的机会。否则,只要线程不退出,value总是会存在一个强引用。但是,要求每个Thread都会退出,是一个极其苛刻的要求。对于线程池来说,大部分线程会一直存在在系统的整个生命周期内,那样的话,就会造成value对象出现泄漏的可能。处理的方法是,当你不需要这个ThreadLocal变量时,主动调用remove(),这样对整个系统是有好处的。

/**
 * 将当前线程局部变量的值删除,目的是为了减少内存占用。主要目的是防止内存泄漏。
 */
public void remove() {
    // 获取当前线程的ThreadLocalMap对象,并将其移除。
    ThreadLocalMap m = getMap(Thread.currentThread());
    if (m != null)
        // 直接移除以当前ThreadLocal为key的value
        m.remove(this);
}

三:ThreadLocalMap中的Hash冲突处理

ThreadLocalMap作为一个HashMap和java.util.HashMap的实现是不同的。对于java.util.HashMap使用的是链表法来处理冲突:
在这里插入图片描述
但是,对于ThreadLocalMap,它使用的是简单的线性探测法,如果发生了元素冲突,那么就使用下一个槽位存放:
在这里插入图片描述

四:可以被继承的ThreadLocal——InheritableThreadLocal

ThreadLocal真的只是当前线程可见吗?

在实际开发过程中,我们可能会遇到这么一种场景。主线程开了一个子线程,但是我们希望在子线程中可以访问主线程中的ThreadLocal对象,也就是说有些数据需要进行父子线程间的传递。

因为在子线程中,是没有threadLocal的。如果我们希望子线可以看到父线程的ThreadLocal,那么就可以使用InheritableThreadLocal。顾名思义,这就是一个支持线程间父子继承的ThreadLocal。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小本科生debug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值