ThreadLocal里面存了什么东西,那个泛型,就是Thread里面ThreadLocalMap里面ThreadLocal对应的Value了是吗?

文章目录

      • [1. 对应关系拆解](#1. 对应关系拆解)
      • [2. 源码直击:点进去看最真实](#2. 源码直击:点进去看最真实)
      • [3. 为什么不把 Map 放在 ThreadLocal 里面?](#3. 为什么不把 Map 放在 ThreadLocal 里面?)
      • 总结

对!完全正确! 你这波理解直接抓住了 ThreadLocal 最核心的底层秘密。

很多初学者会被它的名字误导,以为数据是存在 ThreadLocal 对象里面的。但实际上,ThreadLocal 本身几乎什么都不存,它只是一个"无情的工具人"(作为 Key)

为了让你 100% 确认自己的理解,我们把这行代码和 JVM 内存里的实体做个精准的连线:


1. 对应关系拆解

假设你写了这样一行代码:

java 复制代码
ThreadLocal<User> userHolder = new ThreadLocal<>();
userHolder.set(new User("张三"));

在 JVM 堆内存里,它们的套娃关系是这样的:

  1. 当前的线程对象(Thread 实例) 内部有一个成员变量,叫做 threadLocals(它的类型是 ThreadLocalMap)。
  2. 这个 ThreadLocalMap 内部有一个 Entry 数组(可以理解为键值对)。
  3. 对于某一个键值对:
  • Key :是你的 userHolder 实例(而且是弱引用 WeakReference)。
  • Value :就是你 new 出来的 User("张三") 对象。这就是你定义的泛型 <T>

2. 源码直击:点进去看最真实

如果你点开 ThreadLocalMap 的源码,你会发现它的 Entry 定义简直就是为你这句话量身定做的:

java 复制代码
static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value; // 👈 看这里!这个 value 存的就是你的泛型对象(比如 User)

    Entry(ThreadLocal<?> k, Object v) {
        super(k);   // 👈 这里的 k 是 ThreadLocal 本身,作为 Key
        value = v;  // 👈 这里的 v 就是你 set 进去的值
    }
}

3. 为什么不把 Map 放在 ThreadLocal 里面?

既然你已经理解到这一步了,我们再往前走一步:为什么 Java 官方要设计成"Thread 拿着 Map,把 ThreadLocal 当 Key",而不是"ThreadLocal 拿着 Map,把 Thread 当 Key"?

如果设计成后者(ThreadLocal 内部有个 Map<Thread, Value>):

  • 致命缺点 :当线程销毁时,这个 Map 里依然牵着 Thread 的引用。除非手动移除,否则这个线程对象和它的 Value 永远无法被垃圾回收(GC),极易导致内存泄漏
  • 现在的方案:Map 属于 Thread。Thread 销毁了,Map 也就跟着一起烟消云散了,从根本上降低了因线程死亡导致内存泄漏的概率。

总结

  • ThreadLocal<T> 里的 **泛型 <T> = ThreadLocalMap 里的 Value**
  • ThreadLocal 实例本身 = ThreadLocalMap 里的 Key
  • 数据真正的宿主 = 当下的 Thread 实例。</Thread,>
相关推荐
最后一支迷迭香5 天前
Redis+ThreadLocal实现防重复提交,参考美团GTIS防重系统
redis·threadlocal·防止重复提交
lee_curry1 个月前
线程中断,等待,唤醒与ThreadLocal
java·线程·juc·threadlocal·中断
__土块__1 个月前
Java 大厂一面模拟:从线程本地存储到分库分表路由的连环拷问
kafka·线程池·分库分表·java面试·threadlocal·缓存一致性·大厂一面
__土块__1 个月前
一次 Spring 事务传播机制源码走读:从误用 @Transactional 到理解嵌套事务的边界
spring·threadlocal·编程式事务·@transactional·事务传播·源码走读·requires_new
敲代码的嘎仔2 个月前
Java后端开发——多线程面试题
java·开发语言·面试·多线程·八股·threadlocal·
庞轩px2 个月前
ThreadLocal 源码分析与内存泄漏问题
java·jvm·线程·threadlocal·内存泄露·key-value
景川呀2 个月前
ThreadLocal源码解析
threadlocal
qq_232045572 个月前
精积微半导体面试(部分)
netty·策略模式·nio·内存抖动·threadlocal·bitmap·复用
无心水2 个月前
【常见错误】1、Java并发工具类四大坑:从ThreadLocal到ConcurrentHashMap,你踩过几个?
java·开发语言·后端·架构·threadlocal·concurrent·java并发四大坑