首页 关于我们 成功案例 网络营销 电商设计 新闻中心 联系方式
QQ联系
电话联系
手机联系

j*a threadLocal源码探究

发布时间:2025-12-07 10:17
发布者:网络
浏览次数:
ThreadLocal 的值存在各线程的 ThreadLocalMap 中,以当前 ThreadLocal 为 key(弱引用)、value 为强引用;需手动 remove() 避免因 key 被 GC 后 value 泄漏。

java threadlocal源码探究

ThreadLocal 的核心不是“全局变量”,而是每个线程独享一份副本,靠的是 Thread 对象内部的 ThreadLocalMap。 它不解决共享数据同步问题,而是规避共享——让每个线程操作自己的变量,天然线程安全。

ThreadLocal 的 set() 是怎么存值的?

调用 threadLocal.set(value) 时,并不会把值存在 ThreadLocal 实例里,而是:

  • 获取当前线程(Thread.currentThread()
  • 从该线程对象中拿到它的 threadLocals 字段(类型是 ThreadLocalMap
  • 以当前 ThreadLocal 实例为 key,传入的 value 为 value,存入这个 map

注意:key 是弱引用(WeakReference<threadlocal></threadlocal>),这是为避免内存泄漏埋下的伏笔。

get() 为什么能拿到“自己”的值?

调用 threadLocal.get() 时流程类似:

  • 拿到当前线程
  • 取出它的 threadLocals(可能为 null,首次调用会触发初始化)
  • 在 map 中以当前 ThreadLocal 实例为 key 查找 entry

由于每个线程都有独立的 ThreadLocalMap,所以自然互不干扰。哪怕多个线程用同一个 ThreadLocal 对象,它们操作的其实是各自 map 中的不同槽位。

ThreadLocalMap 是个什么结构?

它不是 HashMap,而是一个定制的、基于开放寻址法的哈希表:

简小派 简小派

简小派是一款AI原生求职工具,通过简历优化、岗位匹配、项目生成、模拟面试与智能投递,全链路提升求职成功率,帮助普通人更快拿到更好的 offer。

简小派 123 查看详情 简小派
  • 底层是 Entry[] table,Entry 继承自 WeakReference<threadlocal></threadlocal>,value 是强引用
  • 没有链表或红黑树,冲突时线性探测(向后找下一个空位)
  • 每次 get/set 都会顺带做“探测式清理”(expungeStaleEntries):扫描并移除 key 已被 GC 的 stale entry

这个设计兼顾了轻量和性能,但也意味着:如果线程长期运行(如线程池中的线程),又没手动 remove(),就可能因 key 被回收而留下 value 泄漏。

为什么必须手动 remove()?

因为 key 是弱引用,GC 可能随时回收 ThreadLocal 对象,但 value 还牢牢挂在 Entry 里。ThreadLocalMap 的清理是被动且不彻底的(只清理探测路径上的 stale entry)。常见场景如 Web 应用中用 ThreadLocal 存用户上下文,在 Filter 或 Interceptor 结束时务必调用 threadLocal.remove()

不 remove 的后果:线程复用时,旧 value 堆积,引发内存泄漏(尤其 value 是大对象或持有外部引用时)。

基本上就这些。理解 ThreadLocal,关键不在“怎么用”,而在“值到底存在哪”和“谁负责清理”。

以上就是j*a threadLocal源码探究的详细内容,更多请关注其它相关文章!


# java  # 为什么  # 好了  # 全局变量  # 转换为  # 时长  # 自己的  # 的是  # 这是  # 是个  # 都有  # 首次  # 南湖时尚网站建设  # hacci营销推广策略  # 清远企业网站推广哪家好  # 网络平台营销推广技巧  # seo seo顺时学院手把手教  # seo教程视频王钊  # 设计推广营销类方案范文  # 行业信息网站如何推广  # x济南seo  # 北京网站推广亅乐云seo十年