ThreadLocal

ThreadLocal类用来提供线程内部的局部变量

ThreadLocal实例 通常来说都是private static类型的,用于关联线程和线程上下文

ThreadLocal与synchronized的区别

synchronized:同步机制采用'以时间换空间'的 方式, 只提供了一份变量,让不同 的线程排队访问;侧重于多个线程之间访问资源的同步

ThreadLocal采用'以空间换时 间'的方式, 为每一个线程都提供 了一份变量的副本,从而实现同 时访问而相不干扰;侧重于多线程中让每个线程之间的数据 相互隔离。

数据结构

每个Thread中都具备一个ThreadLocalMap,而ThreadLocalMap可以存储以ThreadLocal为 key ,Object 对象为 value 的键值对。

ThreadLocal与内存泄漏

相关概念

Memory overflow:内存溢出,没有足够的内存提供申请者使用。

Memory leak: 内存泄漏是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪 费,导致程序运行速度减慢甚至系统崩溃等严重后果。内存泄漏的堆积终将导致内存溢出。

强引用("Strong" Reference),就是我们最常见的普通对象引用,只要还有强引用指向一个对象, 就能表明对象还"活着",垃圾回收器就不会回收这种对象。

弱引用(WeakReference),垃圾回收器一旦发现了只具有弱引用的对象,不管当前内存空间足够与 否,都会回收它的内存。

产生原因

java 复制代码
static class Entry extends WeakReference<ThreadLocal<?>> {
    Object value;

    Entry(ThreadLocal<?> k, Object v) {
        super(k);
        value = v;
    }
}

ThreadLocalMapkeyvalue 引用机制:

  • key 是弱引用ThreadLocalMap 中的 key 是 ThreadLocal 的弱引用 (WeakReference<ThreadLocal<?>>)。 这意味着,如果 ThreadLocal 实例不再被任何强引用指向,垃圾回收器会在下次 GC 时回收该实例,导致 ThreadLocalMap 中对应的 key 变为 null
  • value 是强引用 :即使 key 被 GC 回收,value 仍然被 ThreadLocalMap.Entry 强引用存在,无法被 GC 回收。

ThreadLocal 实例失去强引用后,其对应的 value 仍然存在于 ThreadLocalMap 中,因为 Entry 对象强引用了它。如果线程持续存活(例如线程池中的线程),ThreadLocalMap 也会一直存在,导致 key 为 null 的 entry 无法被垃圾回收,即会造成内存泄漏。

也就是说,内存泄漏的发生需要同时满足两个条件:

  1. ThreadLocal 实例不再被强引用;
  2. 线程持续存活,导致 ThreadLocalMap 长期存在。

为什么必须使用弱引用

如果 ThreadLocal 对线程本地变量(ThreadLocalMap)使用强引用,那么当 ThreadLocal 对象不再被外部引用时,由于 ThreadLocalMap 仍然被线程持有强引用,垃圾回收器无法回收 ThreadLocal 对象,从而可能导致内存泄漏。因为线程的生命周期可能很长,大量的无法被回收的 ThreadLocal 对象会占用内存空间

避免措施

remove()

相关推荐
喝可乐的希饭a17 分钟前
Spring 策略模式实现
java·spring·策略模式
荒诞硬汉21 分钟前
二维数组相关学习
java·算法
我有一只肥螳螂32 分钟前
idea监控本地堆栈
java·ide·intellij-idea
程序员良辰1 小时前
URL与URI:互联网世界的“门牌号“与“身份证“
java·网络协议
ahauedu1 小时前
Apache POI 依赖版本冲突导致 NoSuchFieldError: Factory 报错
java·maven·apache
运维帮手大橙子1 小时前
字符串缓冲区和正则表达式
java·开发语言
丶小鱼丶2 小时前
栈算法之【有效括号】
java·算法
郝学胜-神的一滴3 小时前
SpringBoot实战指南:从快速入门到生产级部署(2025最新版)
java·spring boot·后端·程序人生
鼠鼠我捏,要死了捏6 小时前
Java 虚拟线程在高并发微服务中的实战经验分享
java·microservices·virtualthreads
武子康6 小时前
Java-82 深入浅出 MySQL 内部架构:服务层、存储引擎与文件系统全覆盖
java·开发语言·数据库·学习·mysql·spring·微服务