ThreadLocal 的值存在各线程的 ThreadLocalMap 中,以当前 ThreadLocal 为 key(弱引用)、value 为强引用;需手动 remove() 避免因 key 被 GC 后 value 泄漏。

ThreadLocal 的核心不是“全局变量”,而是每个线程独享一份副本,靠的是 Thread 对象内部的 ThreadLocalMap。 它不解决共享数据同步问题,而是规避共享——让每个线程操作自己的变量,天然线程安全。
调用 threadLocal.set(value) 时,并不会把值存在 ThreadLocal 实例里,而是:
Thread.currentThread())threadLocals 字段(类型是 ThreadLocalMap)注意:key 是弱引用(WeakReference<threadlocal></threadlocal>),这是为避免内存泄漏埋下的伏笔。
调用 threadLocal.get() 时流程类似:
立即学习“Java免费学习笔记(深入)”;
threadLocals(可能为 null,首次调用会触发初始化)由于每个线程都有独立的 ThreadLocalMap,所以自然互不干扰。哪怕多个线程用同一个 ThreadLocal 对象,它们操作的其实是各自 map 中的不同槽位。
它不是 HashMap,而是一个定制的、基于开放寻址法的哈希表:
Entry[] table,Entry 继承自 WeakReference<threadlocal></threadlocal>,value 是强引用这个设计兼顾了轻量和性能,但也意味着:如果线程长期运行(如线程池中的线程),又没手动 remove(),就可能因 key 被回收而留下 value 泄漏。
因为 key 是弱引用,GC 可能随时回收 ThreadLocal 对象,但 value 还牢牢挂在 Entry 里。ThreadLocalMap 的清理是被动且不彻底的(只清理探测路径上的 stale entry)。常见场景如 Web 应用中用 ThreadLocal 存用户上下文,在 Filter 或 Interceptor 结束时务必调用 threadLocal.remove()。
不 remove 的后果:线程复用时,旧 value 堆积,引发内存泄漏(尤其 value 是大对象或持有外部引用时)。
基本上就这些。理解 ThreadLocal,关键不在“怎么用”,而在“值到底存在哪”和“谁负责清理”。
以上就是java threadLocal源码探究的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号