java的threadlocal
Java 的 ThreadLocal 是 Java 语言提供的一个线程局部变量工具类,它让每个线程都能拥有自己独立的一份变量副本。它常出现在多线程编程、框架源码和面试题中,用来解决变量在线程间共享时的安全问题。
基本含义与用途
ThreadLocal 的核心作用是“以线程为键,隔离数据”。你通过 set 存入一个值,只有当前线程能通过 get 取到它,其他线程读不到也改不了。典型用途包括:保存一次请求的上下文信息(如用户身份、追踪 ID)、让非线程安全的对象(如 SimpleDateFormat)在每个线程里各用一份、以及在框架中传递隐式参数。它本质上是用空间换隔离,避免加锁。
常见问题
最需要警惕的是内存泄漏。ThreadLocal 的值存放在线程对象的 ThreadLocalMap 里,键是弱引用,值是强引用。如果线程长期存活(比如线程池中的线程)且用完不调用 remove,值就可能一直无法回收。另一个常见困惑是父子线程传递:普通 ThreadLocal 在子线程里读不到父线程的值,需要改用 InheritableThreadLocal 或框架提供的透传方案。此外,在线程池中复用的线程可能残留上一次任务的值,导致数据串号。
怎么判断与怎么选
判断是否需要 ThreadLocal,可以问自己:这份数据是否只属于当前线程、是否不想通过方法参数层层传递、是否读写频繁但线程间无需共享。如果答案是肯定的,它比较合适。使用时建议遵循“用完即 remove”,尤其在线程池场景。若需要子线程继承,选 InheritableThreadLocal;若涉及异步编排或线程池透传,要考虑专门的上下文传递工具。若数据本来就需要跨线程共享,应改用并发集合或加锁机制,而不是硬套 ThreadLocal。