ThreadLocal

上一篇:并发工具类 · 下一篇:并发容器

是什么#

每个线程 提供独立变量副本,线程间互不干扰,避免共享变量同步。

private static final ThreadLocal<SimpleDateFormat> SDF =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
public String format(Date d) {
return SDF.get().format(d);
}

典型场景:数据库 Connection(老代码)、用户上下文SimpleDateFormat(现更推荐 DateTimeFormatter)、Spring 事务绑定。

原理(简述)#

每个 Thread 持有 ThreadLocalMap(key 为 ThreadLocal 弱引用,value 为副本)。get() 从当前线程 map 取 value。

内存泄漏#

ThreadLocal 被回收后,若线程长期存活(如线程池),map 中 entry 的 value 仍可能无法回收。

实践:用完 remove(),尤其线程池场景:

try {
context.set(user);
// business
} finally {
context.remove();
}

InheritableThreadLocal#

子线程可继承父线程的值;线程池下仍可能不符合预期,异步传递上下文常用 TransmittableThreadLocal(TTL) 等方案。

与 synchronized 对比#

ThreadLocal 空间换时间:每线程一份副本,无锁;适合「每线程独立状态」,不适合「必须全局一致」的数据。

一句话总结#

ThreadLocal 解决「线程内私有状态」;线程池必须 finally 里 remove;父子线程传递慎用 InheritableThreadLocal。

文章目录

文章目录