介绍

ThreadLocal 提供线程局部变量,ThreadLocal实例通常是线程私有静态字段,使用的目的是希望将线程与状态关联起来。与JMM中局部变量有几分相似之处,但是不用写回主内存(如果违反,那就线程不安全),Thread用完要remove(),特别在线程池的情况下,会出现内存泄漏。

Thread、ThreadLocal、ThreadLocalMap



ThreadLocal.ThreadLocalMap 各自线程拥有自己的Map。

  • 注意

    思考:为什么要在线程中使用ThreadLocalMap?为什么是Entry数组

    因为一个线程可以拥有多个ThreadLocal,没错,多个ThreadLocal变量。

强、软、弱、虚



强引用:普通对象引用。

Student a=new Student();
a=null;

软引用:内存足够时保留,内存不够时会回收

弱引用:只要gc就回收

虚引用:在对象回收后进行通知,放入引用队列。

什么是内存泄漏?

不再会被使用的对象,不能被回收。

为什么会出现内存泄漏?

key是弱引用,被回收后,value没有被回收。

threadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal不存在外部强引用时,Key(ThreadLocal)势必会被GC回收,这样就会导致ThreadLocalMap中key为null, 而value还存在着强引用,只有thead线程退出以后,value的强引用链条才会断掉。

但如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:

Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value

永远无法回收,造成内存泄漏。

仔细想想,ThreadLocal 下面这个设计值得学习

  1. Thead 线程中有ThreadLocalMap
  2. 在线程内创建ThreadLocal会自动放进ThreadLocalMap
        ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("123");
    public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = t.threadLocals;
if (map != null) {
map.set(this, value);
} else {
createMap(t, value);
}
}

更新一下,我想给你讲明白ThreadLocal

现在时间2023-07-05-00:37

提前声明,如有理解错误,本人概不负责。


面试官:你好同学,简单一个面试题,八股文,来,对象会创建在什么区域?

小涛:堆(简洁明了,不拖泥带水,声音洪亮)

面试官:offer给你了,拿去。


面试官:那么假如线程执行过程中发生GC,内存不够了嘛,key不是弱引用嘛,发生GC就会销毁,ThreadLocalMap key会不会被销毁,再说明一下问题也就是说key指向的ThreadLocal会不会被回收?

小涛:如回 如来到底来没来 如来

面试官:offer给你了,拿去。,到底回没回收?

首先搞清楚,ThreadLocal 在线程执行过程中,会不会回收?你觉着应不应该被回收,那当然不能被回收,线程中创建的对象放在堆区,线程中局部变量表指向堆区对象,线程执行过程中,指针一直会指向堆区对象(强引用),那么堆中的对象怎么会被回收呢?



那什么时候这些强引用会被销毁呢?线程结束,栈帧弹出,引用是不是没了?假如果ThreadLocalMap 中key是强引用,也就如下图:



那你说说ThreadLocal 对象会不会被回收?那不是有key的强引用嘛。只要ThreadLocalMap不回收,ThreadLocal对象就不会被回收。



设计师设计成弱引用,gc时候发现ThreadLocal对象只有弱引用,那么会直接将对象回收,剩下的ThreadLocalMap话,交给系统进行回收嘛。

面试官:说了这么多,那你说说,现在ThreadLocal为什么会存在内存泄漏的风险?

:ThreadLocalMap交给系统回收?什么时候回收?value中的对象什么时候释放?ThreadLocalMap不回收,value不会释放。所以我们要养成手动remove的好习惯,当然ThreadLocal里面也做了优化,比如某些时候看到Key被回收时,会释放value。

ThreadLocal-全概念解析的更多相关文章

  1. 【原创】Matlab中plot函数全功能解析

    [原创]Matlab中plot函数全功能解析 该帖由Matlab技术论(http://www.matlabsky.com)坛原创,更多精彩内容参见http://www.matlabsky.com 功能 ...

  2. mongodb基本概念解析

    MongoDB 概念解析 不管我们学习什么数据库都应该学习其中的基础概念,在mongodb中基本的概念是文档.集合.数据库,下面我们挨个介绍. 下表将帮助您更容易理解Mongo中的一些概念: SQL术 ...

  3. Matlab中plot函数全功能解析

    Matlab中plot函数全功能解析 功能 二维曲线绘图 语法 plot(Y)plot(X1,Y1,...)plot(X1,Y1,LineSpec,...)plot(...,'PropertyName ...

  4. Android中px, ppi, dpi, dp, dip, sp概念解析

    Android中px, ppi, dpi, dp, dip, sp概念解析

  5. ThreadLocal原理深入解析

    目录 1. 从一次项目经历说起 2. ThreadLocal源码解析 2.1 set方法源码解析 2.2 get方法源码解析 2.3 ThreadLocal源码总结 3. ThreadLocalMap ...

  6. MongoDB学习笔记—概念解析

    Mongo基本概念 下表将帮助您更容易理解Mongo中的一些概念: SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table collection ...

  7. Photoshop入门教程(一):文本新建与概念解析

    写在开头 <Photoshop实用入门>系列教程可能对于一点都没有接触过Photoshop的人来说不太容易接受,因为本教程并没有细致到教你如何使用画笔工具等一系列很基础的东西,有些地方的讲 ...

  8. Feign Ribbon Hystrix 三者关系 | 史上最全, 深度解析

    史上最全: Feign Ribbon Hystrix 三者关系 | 深度解析 疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -25[ 博客园 总入口 ] 前言 疯狂创客圈(笔者尼恩创建的 ...

  9. RabbitMQ安装、集群搭建、概念解析

    RabbitMQ安装.集群搭建.概念解析 基本概念 为什么会产生MQ 1.解耦:采用异步方式实现业务需求达到解耦的目的. 2.缓冲流量,削峰填谷: 问:为什么会有流量冲击? 答:采用"直接调 ...

  10. Kubernetes 弹性伸缩全场景解析 (一)- 概念延伸与组件布局

    传统弹性伸缩的困境 弹性伸缩是Kubernetes中被大家关注的一大亮点,在讨论相关的组件和实现方案之前.首先想先给大家扩充下弹性伸缩的边界与定义,传统意义上来讲,弹性伸缩主要解决的问题是容量规划与实 ...

随机推荐

  1. 微软RDL远程代码执行超高危漏洞(CVE-2024-38077)漏洞检测排查方式

    漏洞名称:微软RDL远程代码执行超高危漏洞(CVE-2024-38077) CVSS core:   9.8 漏洞描述: CVE-2024-38077 是微软近期披露的一个极其严重的远程代码执行漏洞. ...

  2. Angular Material 18+ 高级教程 – CDK Scrolling

    Angular CDK 的意义 经过之前两篇文章 CDK Portal 和 CDK Layout の Breakpoints,我相信大家已经悟到了 CDK 的意义. CDK 有 3 个方向: 包装 B ...

  3. 【赵渝强老师】SQL的字符函数

    字符函数,顾名思义,操作的就是字符串.通过下图,我们来了解一下Oracle的字符函数. 一.大小写控制函数 lower.upper.initcap select lower('Hello World' ...

  4. 关于 JS 函数的一切

    本文基于: Bilibili - 自由的加百利 前置条件: 需掌握函数的编写.传参.返回.调用 理解作用域.掌握定时器的用法 知道引用类型和基本数据类型的区别 知道函数也是引用类型 听说过同步异步的概 ...

  5. 018 人生中第一次用 Python 写的一个小程序_猜年龄(再次强调,重视基础)

    博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...

  6. 鲸鸿动能广告助力App流量高效变现,促进商业增长

    广告是App开发者实现流量变现的常用方法之一.当App积累了一定数量的用户后,开发者需要考虑如何有效地将流量转化为收入,以支持App的商业可持续增长. HarmonyOS SDK广告服务(Ads Ki ...

  7. 云原生爱好者周刊:GitHub 官方文档终于开源了!

    云原生一周动态要闻: API 在 Kubernetes 1.22 中被删除 ContainIQ 公开发布 - Kubernetes 本地实时监控! Sophos 收购 Capsule8 开源项目推荐 ...

  8. Linux 7安装Mysql5.7版本

    Mysql 5.7的安装搭建 首先去到官方网站的下载链接中找到对应你Linux服务器版本的mysql软件包 https://dev.mysql.com/downloads/repo/yum/ 我使用的 ...

  9. SLAM中的各种地图

    1.地图的不同分类方式 地图有多种不同的分类方式,网上有不少帖子介绍各种各样的地图,但并没有非常完整的总结地图应该怎么分类.论文[1]中将地图分成以下几种:拓扑地图.度量地图.度量-语义地图和混合地图 ...

  10. 使用pandas进行数据分析

    目录 1.pandas的特点 2.Series 2.1新建Seriws 2.2使用标签来选择数据 2.3 通过指定位置选择数据 2.4 使用布尔值选择数据 2.5 其他操作 2.5.1 修改数据 2. ...