介绍

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. HTML – script async defer

    参考 Youtube – #3 JavaScript Loading Strategies (async and defer) | JavaScript Full Tutorial no async ...

  2. Linux工具:Winscp显示隐藏的文件

    事件起因: 需要用Winscp上传文件到服务器,然后发现文件被隐藏了 解决办法: Winscp软件的快捷键 : Ctrl + Alt + HWindscp软件的设置方法: 菜单栏 选项 -> 面 ...

  3. 【赵渝强老师】在MongoDB中使用游标

    一.什么是游标? 游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次一行或者多行前进或向后浏览数据的能力. 游标实际上是一种能从包括多条数据记录的结果集 ...

  4. .NET 开源 EF Core 批处理扩展工具,真好用

    前言 Entity Framework Core(EF Core)作为 .NET 生态系统中受欢迎的对象关系映射器(ORM),其轻量级.可扩展性和支持多个数据库引擎而备受青睐. 本文将介绍一款.NET ...

  5. 理解 Vue 的 setup 应用程序钩子

    title: 理解 Vue 的 setup 应用程序钩子 date: 2024/9/30 updated: 2024/9/30 author: cmdragon excerpt: 摘要:本文详细介绍了 ...

  6. .Net 依赖注入深入探索,做一个DI拓展,实现一个简易灵活的 自动依赖注入框架

    一.依赖注入相关知识 1.1.依赖注入的原理和优点 依赖注入(DI),是IOC控制反转思想 的实现.由一个DI容器,去统一管理所有的服务生命周期,服务的创建.销毁.获取,都是由DI容器去处理的. 依赖 ...

  7. 【USB3.0协议学习】Topic4·USB3.0的Port Connect State Machine和设备枚举

    上一节的文章[USB3.0协议学习]Topic2·USB3.0的LTSSM分析中我们详细分析了USB3.0协议中的链路训练状态机(LTSSM)的各状态和跳转条件,覆盖了所有LTSSM状态.本文我们将从 ...

  8. 精彩回顾|【ACDU 中国行·成都站】数据库主题交流活动成功举办!

    2023年10月14日下午,[ACDU 中国行·成都站]在成都市武侯区星宸假日酒店圆满落下帷幕.本次活动由中国数据库联盟(ACDU)联合墨天轮社区主办,围绕「数据库技术及应用」这一主题,六位数据库资深 ...

  9. iOS程序内语言切换使用小结

    随着时代的发展,应用程序相继出现了不同语言的版本方案,中文,英文,法文,韩文等等:想在应用程序中实现语言的自由切换,需要配置多个语言的文件,根据用户的动态选择获取不同语言文件下的语言文件,从而显示到界 ...

  10. 封装JWT - 生成 jwt 和解析 jwt

    1. ASP.NET Core 身份验证和授权验证的功能由Authentication,Authorization中间件提供 :app.UseAuthentication(),app.UseAutho ...