news 2026/4/8 14:24:02

引用指向实际存储的值

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
引用指向实际存储的值

一、核心原理
1. 数据存储结构
// 每个 Thread 对象内部都有一个 ThreadLocalMap
ThreadLocal.ThreadLocalMap threadLocals = null;

// ThreadLocalMap 内部使用 Entry 数组,Entry 继承自 WeakReference<ThreadLocal<?>>
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k); // 弱引用指向 ThreadLocal 实例
value = v; // 强引用指向实际存储的值
}
}
AI写代码

2. 关键设计
线程隔离:每个线程有自己的 ThreadLocalMap 副本
哈希表结构:使用开放地址法解决哈希冲突
弱引用键:Entry 的 key(ThreadLocal 实例)是弱引用
延迟清理:set / get 时自动清理过期条目
二、源码分析
1. set() 方法流程
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value); // this指当前ThreadLocal实例
} else {
createMap(t, value);
}
}

ThreadLocal 是强大的线程隔离工具,但需要谨慎使用。在 Web 应用和线程池场景中,必须在 finally 块中调用 remove(),这是避免内存泄漏的关键。

面试回答
关于 ThreadLocal,我从原理、场景和内存泄漏三个方面来说一下我的理解。

1. 首先,它的核心原理是什么?
简单来说,ThreadLocal 是一个线程级别的变量隔离工具。它的设计目标就是让同一个变量,在不同的线程里有自己独立的副本,互不干扰。

底层结构:每个线程(Thread对象)内部都有一个自己的 ThreadLocalMap(你可以把它想象成一个线程私有的、简易版的HashMap)。
怎么存:当我们调用 ThreadLocal.set(value) 时,实际上是以当前的 ThreadLocal 实例自身作为 Key,要保存的值作为 Value,存入当前线程的那个 ThreadLocalMap 里。
怎么取:调用 ThreadLocal.get() 时,也是用自己作为 Key,去当前线程的 Map 里查找对应的 Value。
打个比方:就像去银行租保险箱。Thread 是银行,ThreadLocalMap 是银行里的一排保险箱,ThreadLocal 实例就是你手里那把特定的钥匙。你用这把钥匙(ThreadLocal实例)只能打开属于你的那个格子(当前线程的Map),存取自己的东西(Value),完全看不到别人格子的东西。不同的人(线程)即使用同一款钥匙(同一个ThreadLocal实例),打开的也是不同银行的格子,东西自然隔离了。
2. 其次,它的典型使用场景有哪些?
正是因为这种线程隔离的特性,它特别适合用来传递一些需要在线程整个生命周期内、多个方法间共享,但又不能(或不想)通过方法参数显式传递的数据。最常见的有两个场景:

场景一:保存上下文信息(最经典)
比如在 Web 应用 或 RPC 框架 中处理一个用户请求时,这个请求从进入系统到返回响应,全程可能由同一个线程处理。我们会把一些信息(比如用户ID、交易ID、语言环境)存到一个 ThreadLocal 里。这样,后续的任何业务方法、工具类,只要在同一个线程里,就能直接 get() 到这些信息,避免了在每一个方法签名上都加上这些参数,代码会简洁很多。
场景二:管理线程安全的独享资源
典型例子是 数据库连接 和 SimpleDateFormat。
像 SimpleDateFormat 这个类,它不是线程安全的。如果做成全局共享,就要加锁,性能差。用 ThreadLocal 的话,每个线程都拥有自己的一个 SimpleDateFormat 实例,既避免了线程安全问题,又因为线程复用了这个实例,减少了创建对象的开销。
类似的,在一些需要保证数据库连接线程隔离(比如事务管理)的场景,也会用到 ThreadLocal 来存放当前线程的连接。
3. 最后,关于它的内存泄漏问题
ThreadLocal 如果使用不当,确实可能导致内存泄漏。它的根源在于 ThreadLocalMap 中 Entry 的设计。

问题根源:
ThreadLocalMap 的 Key(也就是 ThreadLocal 实例)是一个 弱引用。这意味着,如果外界没有强引用指向这个 ThreadLocal 对象(比如我们把 ThreadLocal 变量设为了 null),下次垃圾回收时,这个 Key 就会被回收掉,于是 Map 里就出现了一个 Key 为 null,但 Value 依然存在的 Entry。
这个 Value 是一个强引用,只要线程还活着(比如用的是线程池,线程会复用,一直不结束),这个 Value 对象就永远无法被回收,造成了内存泄漏。
如何避免:
良好习惯:每次使用完 ThreadLocal 后,一定要手动调用 remove() 方法。这不仅是清理当前值,更重要的是它会清理掉整个 Entry,这是最有效、最安全的做法。

https://www.zhihu.com/zvideo/1993467396434981280
https://www.zhihu.com/zvideo/1993467396434981280/
https://www.zhihu.com/zvideo/1993467400620900439
https://www.zhihu.com/zvideo/1993467400620900439/
https://www.zhihu.com/zvideo/1993467404890699415
https://www.zhihu.com/zvideo/1993467404890699415/
https://www.zhihu.com/zvideo/1993467409340846701
https://www.zhihu.com/zvideo/1993467409340846701/
https://www.zhihu.com/zvideo/1993467421995049413
https://www.zhihu.com/zvideo/1993467421995049413/
https://www.zhihu.com/zvideo/1993467417683309465
https://www.zhihu.com/zvideo/1993467417683309465/
https://www.zhihu.com/zvideo/1993467413203813155
https://www.zhihu.com/zvideo/1993467413203813155/
https://www.zhihu.com/zvideo/1993467434842215582
https://www.zhihu.com/zvideo/1993467434842215582/
https://www.zhihu.com/zvideo/1993467430010381183
https://www.zhihu.com/zvideo/1993467430010381183/
https://www.zhihu.com/zvideo/1993467439002952502
https://www.zhihu.com/zvideo/1993467439002952502/
https://www.zhihu.com/zvideo/1993467426004805191
https://www.zhihu.com/zvideo/1993467426004805191/
https://www.zhihu.com/zvideo/1993467443734157142
https://www.zhihu.com/zvideo/1993467443734157142/
https://www.zhihu.com/zvideo/1993467452101772535
https://www.zhihu.com/zvideo/1993467452101772535/
https://www.zhihu.com/zvideo/1993467448113001328
https://www.zhihu.com/zvideo/1993467448113001328/
https://www.zhihu.com/zvideo/1993467456023441573
https://www.zhihu.com/zvideo/1993467456023441573/
https://www.zhihu.com/zvideo/1993467459991266318
https://www.zhihu.com/zvideo/1993467459991266318/
https://www.zhihu.com/zvideo/1993467484938995237
https://www.zhihu.com/zvideo/1993467484938995237/
https://www.zhihu.com/zvideo/1993467468501512666
https://www.zhihu.com/zvideo/1993467468501512666/
https://www.zhihu.com/zvideo/1993467488206358217
https://www.zhihu.com/zvideo/1993467488206358217/
https://www.zhihu.com/zvideo/1993467490735506110
https://www.zhihu.com/zvideo/1993467490735506110/
https://www.zhihu.com/zvideo/1993467493122074164
https://www.zhihu.com/zvideo/1993467493122074164/
https://www.zhihu.com/zvideo/1993467513976161749
https://www.zhihu.com/zvideo/1993467513976161749/
https://www.zhihu.com/zvideo/1993467519080604309
https://www.zhihu.com/zvideo/1993467519080604309/
https://www.zhihu.com/zvideo/1993467495395373192
https://www.zhihu.com/zvideo/1993467495395373192/
https://www.zhihu.com/zvideo/1993467507017815731
https://www.zhihu.com/zvideo/1993467507017815731/
https://www.zhihu.com/zvideo/1993467500030092716
https://www.zhihu.com/zvideo/1993467500030092716/
https://www.zhihu.com/zvideo/1993467516589197267
https://www.zhihu.com/zvideo/1993467516589197267/
https://www.zhihu.com/zvideo/1993467476713947732
https://www.zhihu.com/zvideo/1993467476713947732/
https://www.zhihu.com/zvideo/1993467533521613676
https://www.zhihu.com/zvideo/1993467533521613676/
https://www.zhihu.com/zvideo/1993467511618963254
https://www.zhihu.com/zvideo/1993467511618963254/
https://www.zhihu.com/zvideo/1993467526324187780
https://www.zhihu.com/zvideo/1993467526324187780/
https://www.zhihu.com/zvideo/1993467531072148050
https://www.zhihu.com/zvideo/1993467531072148050/
https://www.zhihu.com/zvideo/1993467509374985521
https://www.zhihu.com/zvideo/1993467509374985521/
https://www.zhihu.com/zvideo/1993467497714821003
https://www.zhihu.com/zvideo/1993467497714821003/
https://www.zhihu.com/zvideo/1993467502261471215
https://www.zhihu.com/zvideo/1993467502261471215/
https://www.zhihu.com/zvideo/1993467523983762556
https://www.zhihu.com/zvideo/1993467523983762556/
https://www.zhihu.com/zvideo/1993467521467172304
https://www.zhihu.com/zvideo/1993467521467172304/
https://www.zhihu.com/zvideo/1993467504513811689
https://www.zhihu.com/zvideo/1993467504513811689/
https://www.zhihu.com/zvideo/1993467528731727409
https://www.zhihu.com/zvideo/1993467528731727409/
https://www.zhihu.com/zvideo/1993467546561704442
https://www.zhihu.com/zvideo/1993467546561704442/
https://www.zhihu.com/zvideo/1993467549736780479
https://www.zhihu.com/zvideo/1993467549736780479/
https://www.zhihu.com/zvideo/1993467544250643770
https://www.zhihu.com/zvideo/1993467544250643770/
https://www.zhihu.com/zvideo/1993467541692125641
https://www.zhihu.com/zvideo/1993467541692125641/
https://www.zhihu.com/zvideo/1993467538349257003
https://www.zhihu.com/zvideo/1993467538349257003/
https://www.zhihu.com/zvideo/1993467535870415071
https://www.zhihu.com/zvideo/1993467535870415071/
https://www.zhihu.com/zvideo/1993467552039445173
https://www.zhihu.com/zvideo/1993467552039445173/
https://www.zhihu.com/zvideo/1993467557102000084
https://www.zhihu.com/zvideo/1993467557102000084/
https://www.zhihu.com/zvideo/1993467561338226646
https://www.zhihu.com/zvideo/1993467561338226646/
https://www.zhihu.com/zvideo/1993467565540918195
https://www.zhihu.com/zvideo/1993467565540918195/
https://www.zhihu.com/zvideo/1993467569483556409
https://www.zhihu.com/zvideo/1993467569483556409/
https://www.zhihu.com/zvideo/1993467573854049391
https://www.zhihu.com/zvideo/1993467573854049391/
https://www.zhihu.com/zvideo/1993467577985422900
https://www.zhihu.com/zvideo/1993467577985422900/
https://www.zhihu.com/zvideo/1993467582313931703
https://www.zhihu.com/zvideo/1993467582313931703/
https://www.zhihu.com/zvideo/1993467590908064293
https://www.zhihu.com/zvideo/1993467590908064293/
https://www.zhihu.com/zvideo/1993467586831218380
https://www.zhihu.com/zvideo/1993467586831218380/
https://www.zhihu.com/zvideo/1993467595970606210
https://www.zhihu.com/zvideo/1993467595970606210/
https://www.zhihu.com/zvideo/1993467600148137561
https://www.zhihu.com/zvideo/1993467600148137561/
https://www.zhihu.com/zvideo/1993467604359213298
https://www.zhihu.com/zvideo/1993467604359213298/
https://www.zhihu.com/zvideo/1993467608469616334
https://www.zhihu.com/zvideo/1993467608469616334/
https://www.zhihu.com/zvideo/1993467612609401111
https://www.zhihu.com/zvideo/1993467612609401111/
https://www.zhihu.com/zvideo/1993467616598180964
https://www.zhihu.com/zvideo/1993467616598180964/
https://www.zhihu.com/zvideo/1993467643966017605
https://www.zhihu.com/zvideo/1993467643966017605/
https://www.zhihu.com/zvideo/1993467669714866366
https://www.zhihu.com/zvideo/1993467669714866366/
https://www.zhihu.com/zvideo/1993467702958895449
https://www.zhihu.com/zvideo/1993467702958895449/
https://www.zhihu.com/zvideo/1993467648760099111
https://www.zhihu.com/zvideo/1993467648760099111/
https://www.zhihu.com/zvideo/1993467646222550938
https://www.zhihu.com/zvideo/1993467646222550938/
https://www.zhihu.com/zvideo/1993467625020343989
https://www.zhihu.com/zvideo/1993467625020343989/
https://www.zhihu.com/zvideo/1993467659161974299
https://www.zhihu.com/zvideo/1993467659161974299/
https://www.zhihu.com/zvideo/1993467637401928552
https://www.zhihu.com/zvideo/1993467637401928552/
https://www.zhihu.com/zvideo/1993467677176513675
https://www.zhihu.com/zvideo/1993467677176513675/
https://www.zhihu.com/zvideo/1993467694863914712
https://www.zhihu.com/zvideo/1993467694863914712/
https://www.zhihu.com/zvideo/1993467663964463781
https://www.zhihu.com/zvideo/1993467663964463781/
https://www.zhihu.com/zvideo/1993467651570303523
https://www.zhihu.com/zvideo/1993467651570303523/
https://www.zhihu.com/zvideo/1993467684533342850
https://www.zhihu.com/zvideo/1993467684533342850/
https://www.zhihu.com/zvideo/1993467672277557358
https://www.zhihu.com/zvideo/1993467672277557358/
https://www.zhihu.com/zvideo/1993467679466622988
https://www.zhihu.com/zvideo/1993467679466622988/
https://www.zhihu.com/zvideo/1993467630250644070
https://www.zhihu.com/zvideo/1993467630250644070/
https://www.zhihu.com/zvideo/1993467661439489485
https://www.zhihu.com/zvideo/1993467661439489485/
https://www.zhihu.com/zvideo/1993467656532144708
https://www.zhihu.com/zvideo/1993467656532144708/
https://www.zhihu.com/zvideo/1993467681932865699
https://www.zhihu.com/zvideo/1993467681932865699/
https://www.zhihu.com/zvideo/1993467666355220836
https://www.zhihu.com/zvideo/1993467666355220836/
https://www.zhihu.com/zvideo/1993467635116048773
https://www.zhihu.com/zvideo/1993467635116048773/
https://www.zhihu.com/zvideo/1993467692229866331
https://www.zhihu.com/zvideo/1993467692229866331/
https://www.zhihu.com/zvideo/1993467689952379632
https://www.zhihu.com/zvideo/1993467689952379632/
https://www.zhihu.com/zvideo/1993467687196706597
https://www.zhihu.com/zvideo/1993467687196706597/
https://www.zhihu.com/zvideo/1993467674550890725
https://www.zhihu.com/zvideo/1993467674550890725/
https://www.zhihu.com/zvideo/1993467697678284364
https://www.zhihu.com/zvideo/1993467697678284364/
https://www.zhihu.com/zvideo/1993467705819431480
https://www.zhihu.com/zvideo/1993467705819431480/
https://www.zhihu.com/zvideo/1993467700312311444
https://www.zhihu.com/zvideo/1993467700312311444/
https://www.zhihu.com/zvideo/1993467708315043343
https://www.zhihu.com/zvideo/1993467708315043343/
https://www.zhihu.com/zvideo/1993467713511773208
https://www.zhihu.com/zvideo/1993467713511773208/
https://www.zhihu.com/zvideo/1993467710957441843
https://www.zhihu.com/zvideo/1993467710957441843/

设计保障:ThreadLocal 本身也做了一些努力,比如在 set()、get()、remove() 的时候,会尝试去清理那些 Key 为 null 的过期 Entry。但这是一种“被动清理”,不能完全依赖。
代码层面:尽量将 ThreadLocal 变量声明为 static final,这样它的生命周期就和类一样长,不会被轻易回收,减少了产生 null Key 的机会。但这并不能替代 remove(),因为线程池复用时,上一个任务的值可能会污染下一个任务。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/4 22:25:49

时自动清理过期条目

一、核心原理 1. 数据存储结构 // 每个 Thread 对象内部都有一个 ThreadLocalMap ThreadLocal.ThreadLocalMap threadLocals null;// ThreadLocalMap 内部使用 Entry 数组&#xff0c;Entry 继承自 WeakReference<ThreadLocal<?>> static class Entry extends We…

作者头像 李华
网站建设 2026/4/8 5:35:46

基于Python+Django的美容院管理系统设计与实现

前言 &#x1f31e;博主介绍&#xff1a;✌CSDN特邀作者、全栈领域优质创作者、10年IT从业经验、码云/掘金/知乎/B站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战&#xff0c;以及程序定制化开发、文档编写、答疑辅导等。✌…

作者头像 李华
网站建设 2026/4/1 22:19:43

STM32+串口字符型LCD显示方案:系统学习路径

从零开始玩转 STM32 串口字符型LCD&#xff1a;不只是“打印Hello World”你有没有遇到过这样的场景&#xff1f;项目做了一半&#xff0c;突然发现MCU的GPIO快被外设占满了——按键、传感器、通信模块……结果连一个1602 LCD都接不上&#xff0c;因为传统的并行驱动要占用整整…

作者头像 李华
网站建设 2026/4/8 13:08:19

51单片机蜂鸣器项目入门:制作简易音乐播放器

用51单片机“弹”一首《小星星》&#xff1a;从蜂鸣器发声到音乐播放的完整实现你有没有想过&#xff0c;一块几块钱的51单片机&#xff0c;加上一个小小的蜂鸣器&#xff0c;也能“演奏”出旋律&#xff1f;不是单调的“嘀嘀”提示音&#xff0c;而是真正能听出调子的《小星星…

作者头像 李华
网站建设 2026/4/4 15:27:55

程序员失业再就业了,喜忧参半

这是小红书上一位上海的Java程序员失业想转行的分享贴。 Java开发的就业市场正在经历结构性调整&#xff0c;竞争日益激烈 传统纯业务开发岗位&#xff08;如仅完成增删改查业务的后端工程师&#xff09;的需求&#xff0c;特别是入门级岗位&#xff0c;正显著萎缩。随着企业…

作者头像 李华
网站建设 2026/3/30 13:44:49

Nginx之rewrite重写功能

目录 一、rewrite概述 1、rewrite功能 2、跳转场景 二、标准配置指令 1、rewrite日志记录指令 2、未初始化变量告警日志记录指令 3、rewrite 指令 3.1 正则表达式 三、rewrite模块使用实例 1.基于域名的跳转 2.基于客户端 IP 访问跳转 3.?基于旧域名跳转到新域名后…

作者头像 李华