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()

相关推荐
折哥的程序人生 · 物流技术专研7 小时前
第4篇:Lambda 简化策略模式(Java 8+)
java·设计模式·策略模式·函数式编程·lambda·代码简化·扩充系列
researcher-Jiang7 小时前
高性能计算之OpenMP——超算习堂学习1
android·java·学习
西门吹-禅9 小时前
java springboot N+1问题
java·开发语言·spring boot
DLYSB_9 小时前
生命通道:如何用 HIS 医疗系统直连网络声光终端,打造“零延误”的危急值响应网关?
java·网络·数据库·报警灯
weixin_BYSJ19879 小时前
SpringBoot + MySQL 乒乓球运动员信息管理系统项目实战--附源码04954
java·javascript·spring boot·python·django·flask·php
AI小码9 小时前
LLM 应用的缓存工程:当每次 API 调用都在燃烧成本
java·人工智能·spring·计算机·llm·编程·api
Hui Baby10 小时前
Spring Security
java·后端·spring
IT笔记11 小时前
【Rust】Rust Match 模式匹配详解
java·开发语言·rust
我才是银古11 小时前
构建 Java GIS 工具库:从碎片化 API 到统一抽象的设计实践
java·gis·geotools·gdal·esri
TPBoreas11 小时前
配置信息防泄露方案:.env 环境隔离详解(dotenv-java)
java·开发语言