介绍

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. 携手华为云WeLink,合合信息旗下名片全能王推动人脉管理数智化升级

    名片是商务场景中信息传递的重要载体.在无纸化办公日益兴盛的当下,数字名片逐渐被广大职场人士接受,成为商务交流的新方式.近期,合合信息旗下名片全能王与华为云WeLink联合研发,升级数字名片" ...

  2. RxJS 系列 – Join Operators

    前言 前几篇介绍过了 Creation Operators Filtering Operators Join Creation Operators Error Handling Operators T ...

  3. ASP.NET Core – 读写 Request / Response

    需求 常见的需求就是从 request 里面读取一些 information. 比如 request URL, header, cookie, 写入 response header, cookie 实 ...

  4. 一文搞定WeakHashMap

    写在前面 在缓存场景下,由于内存是有限的,不能缓存所有对象,因此就需要一定的删除机制,淘汰掉一些对象.这个时候可能很快就想到了各种Cache数据过期策略,目前也有一些优秀的包提供了功能丰富的Cache ...

  5. Windows应急响应-QQ巨盗病毒

    目录 病毒背景 样本分析 开启监控 感染病毒 分析病毒行为 C盘文件监控 D盘文件监控 进程监控排查 服务排查 启动项排查 查杀 1.杀掉进程 2.异常服务 3.映像劫持处理 4.hosts文件处理 ...

  6. CF708C Centroids [树形DP,换根DP]

    Description 给定一棵树. 至多进行一次操作:删去一条边,连接一条新边,保证操作完后仍是树. 问每个点在进行操作后是否可以成为树的重心. Solution 性质\(1\):若一个点不是树的重 ...

  7. ByConity与主流开源OLAP引擎(Clickhouse、Doris、Presto)性能对比分析

    引言: 随着数据量和数据复杂性的不断增加,越来越多的企业开始使用OLAP(联机分析处理)引擎来处理大规模数据并提供即时分析结果.在选择OLAP引擎时,性能是一个非常重要的因素. 因此,本文将使用TPC ...

  8. PostgreSQL 15 新特性解读 | 墨天轮优质文章合集

    5月19日,PostgreSQL 全球开发组宣布 PostgreSQL 15 的第一个 beta 版本,这一新版本在开发者体验.性能表现等方面都有提升.为了帮助大家更快速了解到PostgreSQL 1 ...

  9. Xcode 12 引用缺失包:libstdc++.tbd libstdc++.6.tbd libstdc++.6.0.9.tbd引发的一系列问题解析

    升级到xcode12后会有libstdc++.tbd libstdc++.6.tbd libstdc++.6.0.9.tbd 等库缺失的情况,并引发一些列的 Undefined symbols for ...

  10. C#中的原始字符串

    // 原始字符串使用 三个引号(至少三对)包裹,ps: 引号单独占用一行 // 原始字符串使用变量需要加两个 $$"""{变量}""" st ...