谈谈你对ThreadLocal的理解

1. ThreadLocal的作用

1.1 解决问题

可用于解决线程安全问题

1.2 解决方案

每个线程保存一份自己的对象,ThreadLocal这个作用就是让线程自己独立保存一份自己的变量副本。每个线程都独立使用自己的变量副本,这样就不会影响其他的线程。

也就是说每个线程都会复制一份对象到自己的线程里面去,线程之间是隔离的,所以不会出现线程之间使用同一份资源而造成问题。

1.3 贡献

ThreadLocal是为多线程环境下变量安全提供的一种解决思路,ThreadLocal是为每个线程建立一份自己的单独的变量副本。

每个线程都可以独立地去改变自己的变量副本,从而不会影响其他的线程。ThreadLocal内部有个非常重要的内部类——ThreadLocalMap,该类是实现线程隔离的关键

2. ThreadLocalMap

内部类似于map,但不是map,它是由键值对key、value组成的一个Entry数组

key是ThreadLocal本身的一个弱引用,value就是对应的线程变量副本

ThreadLocal本身是不存储值的,他只是提供一个能查到这个值的key

ThreadLocal包含在这个Thread中,而不是Thread包含在ThreadLocal中。

在这里插入图片描述
这个类图左边是Thread,他有内部属性threadLocals,这个属性其实就是指向这个ThreadLocal,右边这部分他是一个ThreadLocal。

ThreadLocal里面,他又包含这个内部类,内部就是由这个Entry数组组成。每个Entry由key、value组成的:

  1. key就是ThreadLocal这个弱引用。
  2. value就是存进来的这个变量副本。
    在这里插入图片描述
    ThreadLocalMap是由一个Entry数组组成,然后每一个Entry里面是由这个key、value组成的。它的key是ThreadLocal的这个引用,value是实际存储的值。

3. 堆和栈之间的关系图

左边是一个栈,里面放了一个ThreadLocal的引用和一个当前线程的引用

在这里插入图片描述
当前线程是一个ThreadLocalMap,ThreadLocalMap里面分为key和value,key和value组成一个entry。

他的value是一个50M的值,key是由threadlocal去引用的(一个弱引用的关系)。

每一个Thread线程内部都有一个ThreadLocalMap。这个map里面,key是ThreadLocal这个引用,他的value就是你要操作的这个变量值。

Thread内部的ThreadLocalMap是由这个ThreadLocal去维护的。由这个ThreadLocal负责向这个map里面去设置值,添加值,删除值等等操作。

4. ThreadLocal中的方法

4.1 get方法

用来获取ThreadLocal在当前线程中保存的变量副本。

  1. 获取当前线程,去获取到这个ThreadLocalMap.
  2. 通过这个线程里面的threadLocals去拿到这个ThreadLocalMap,然后拿到的map不为空,那么就把这个值拿出来返回。如果没有取到这个值,就初始化这个值。

4.2 set方法

用来设置当前线程中变量的副本。

把当前线程中的ThreadLocalMap拿出来,如果这个map值不为空,那么就把这个map的值更新一下,如果为空,则创建这个map。

4.3 remove方法

用来移除当前线程中变量的副本。

4.4 initialValue方法

一个protected方法,一般是用来在使用时进行重写的。

5. 数据结构

数组+开放地址法

6. 内存泄露问题

在这里插入图片描述
Entry继承这个弱引用的时候,只是对key做了弱引用,对value还是强引用。弱引用能帮助程序更好地去进行垃圾回收。

如果一个ThreadLocal没有外部强引用来引用它,那么下一次系统GC的时候,这个ThreadLocal弱引用肯定是会被回收的

这样一来,这个ThreadLocalMap就出现了key为null的Entry,也就没有办法通过这个key找到value,然后这个value又是强引用的,如果线程一直存在的话,他就会一直存在这个value,就会造成内存泄露的问题,一直不会被GC掉,被垃圾回收掉。

get方法,set方法还有remove方法会对这个key为null的Entry进行清除。

6.1 如何避免内存泄露

使用完ThreadLocal后就手动地调用remove方法即可。

参考资料:【真实工作场景】中怎么用ThreadLocal

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值