JAVA面试题分享三十三:ThreadLocal的内部结构?

一、前言

ThreadLocal是Java中一个很有用的工具类,它提供了一种线程本地变量的机制,使得每个线程都可以独立地使用一个变量副本,互不干扰。在本文中,我们将讨论ThreadLocal的实现方式和其内部数据结构。

二、什么是ThreadLocal

ThreadLocal提供了线程的局部变量,每个线程都可以通过set()和get()来对这个局部变量进行操作,但不会和其他线程的局部变量进行冲突,实现了线程的数据隔离。

简而言之:ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是不可见的。

三、ThreadLocal的实现方式

ThreadLocal的实现方式是通过维护一个ThreadLocalMap来存储每个线程的变量副本。每个ThreadLocal对象都有一个唯一的ID作为key,在ThreadLocalMap中以key-value的形式存储数据。

当通过ThreadLocal的get()方法获取变量副本时,首先会获取当前线程的ThreadLocalMap对象,然后以ThreadLocal对象本身作为key,在ThreadLocalMap中查找对应的value。

当通过ThreadLocal的set()方法设置变量副本时,同样会先获取当前线程的ThreadLocalMap对象,然后将ThreadLocal对象本身作为key,要设置的value作为value,存储到ThreadLocalMap中。

当一个线程结束时,若ThreadLocalMap对象没有被垃圾回收,则会一同释放ThreadLocalMap中所有的key-value。这样可以避免内存泄漏。

  • 每个Thread维护着一个ThreadLocalMap的引用
  • ThreadLocalMap是ThreadLocal的内部类,用Entry来进行存储
  • 调用ThreadLocal的set()方法时,实际上就是往ThreadLocalMap设置值,key是ThreadLocal对象,值是传递进来的对象
  • 调用ThreadLocal的get()方法时,实际上就是在ThreadLocalMap获取值,key是ThreadLocal对象
  • ThreadLocal本身并不存储值,它只是作为一个key来让线程从ThreadLocalMap获取value。

四、ThreadLocal的内部数据结构

ThreadLocal的内部数据结构是基于ThreadLocalMap的。ThreadLocalMap是一个自定义的散列表,采用开放地址法处理冲突。

ThreadLocalMap中的Entry数组是懒加载的,在第一次put操作时初始化。Entry中存储了ThreadLocal的引用作为key,以及对应的value。

在进行查找和插入操作时,ThreadLocalMap使用线性探测来处理冲突。当发生冲突时,会线性地检查下一个位置是否为空,直到找到一个空的位置或者遇到一个相同的key。

当数组元素个数大于等于容量的2/3时,会触发扩容操作。扩容时,会创建一个容量为原来两倍的新数组,并将原来数组中的元素重新映射到新的数组。

值得注意的是,ThreadLocalMap使用ThreadLocal的弱引用作为key,而不是强引用。这是为了防止内存泄漏,因为ThreadLocal对象可能在其它地方被删除,但该线程的ThreadLocalMap仍然保留对ThreadLocal的引用。

总结一下,ThreadLocal的实现方式是通过维护一个ThreadLocalMap来存储每个线程的变量副本,其内部数据结构是基于ThreadLocalMap的散列表,采用开放地址法处理冲突。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

之乎者也·

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

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

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

打赏作者

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

抵扣说明:

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

余额充值