ThreadLLocal的学习

news2024/9/26 1:23:08

ThreadLocal的学习

  • ThreadLocal的学习
    • 1.ThreadLocal是什么?
    • 2.ThreadLocal的数据结构
      • Java的四种引用类型
    • 3.ThreadLocal为什么会出现内存泄露?
      • 既然会出现内存泄露为什么Entry的key还要使用弱引用?
      • 如何避免内存泄露?

ThreadLocal的学习

1.ThreadLocal是什么?

ThreadLocal对象可以提供局部变量,每个线程Thread拥有一份自己的副本变量,每个线程Thread拥有一份自己的副本变量,多个线程互不干扰。

2.ThreadLocal的数据结构

Thread类有一个类型为ThreadLocal.ThreadLocalMap的实例变量threadlocals

也就是说每个线程都有一个自己的ThreadLocalMap

ThreadLocal.ThreadLocalMap threadLocals=null;

ThreadLocalMap中维护了k-v形式的Entry对象

其中key视为ThreadLocal,value就是我们在ThreadLocal中存储的值

ThreadLocalMap有点类似HashMap的结构,只是HashMap是由数组+链表实现的,而ThreadLocalMap中没有链表结构

注意:

key并不是ThreadLocal本身,而是它的一个弱引用(因为继承自WeakReference

由此,ThreadLocal本身是不存储值的,我们在使用其对应的set和get方法的时候都是操作的其对应的ThreadLocalMap对象。

也就是说每个线程在往ThreadLocal里存值的时候都会往自己的ThreadLocalMap里存,读也是以ThreadLocal作为引用,在自己的map里找对应的key。这就是线程隔离

Java的四种引用类型

Java中由值类型也有引用类型,引用类型一般是针对Java中的对象来说的。

Java为引用类型专门定义了一个类叫做Reference

Reference是跟Java垃圾回收机制息息相关的类。

  1. 强引用 Strong Reference

    Java中的引用默认就是强引用,任何一个对象的赋值操作就产生了对这个对象的强引用

    Object obj=new Object()
    

    我们new了一个Object对象并将其赋值给obj,这个boj就是new Object()的强引用

    强引用的特征就是只要有强引用存在,被引用的对象就不会被回收(也就是new Object()不会被回收)

  2. 软引用 Soft Reference

    只有在内存不足的情况下,被引用的对象才会被回收

    public class SoftReference<T> extends Reference<T>{
            public SoftReference(T referent) {
                /**/
            }
            public SoftReference(T referent, ReferenceQueue<? super T> q) {
                /**/
            }
    
    }
    

    SoftReference继承自Reference,有两种构造函数

    T referent:就是软引用对象

    ReferenceQueue<? super T> q:就是用来存储封装的待回收的Reference对象,eferenceQueue中的对象是由Reference类中的ReferenceHandler内部类进行处理的。

  3. 弱引用 Weak Reference

    弱引用和软引用类似,但是弱引用的对象(即被引用的对象)只要垃圾回收执行不管内存是否充足都会被回收(只有弱引用的时候

  4. 虚引用 Phantom Reference

    虚引用是最弱的引用,引用的是需要被垃圾回收的对象

    虚引用中唯一的作用就是用队列接收对象即将死亡的通知

    所以在类的定义中,get一直返回的都是null

    PhantomReference只有一个构造函数并且必须传入ReferenceQueue

    public class PhantomReference<T> extends Reference<T>{
        public PhantomReference(T referent, ReferenceQueue<? super T> q){
            /**/
        }
    }
    

    ReferenceQueue<? super T> q:就是用来存储封装的待回收的Reference对象。

    虚引用跟踪垃圾回收器(gc)收集对象的活动,在GC的过程中,如果发现有PhantomReference,GC则会将引用放到ReferenceQueue中,由程序员自己处理(这个和软引用是不一样的)

    当程序员调用ReferenceQueue.pull()方法,将引用出ReferenceQueue移除之后,Reference对象会变成Inactive状态,意味着被引用的对象可以被回收了。

3.ThreadLocal为什么会出现内存泄露?

在这里插入图片描述

在当前线程正在运行的时候,如果发生GC,此时ThreadLocal对象没有被其它地方强引用的时候(即只有弱引用),key指向的ThreadLocal的虚引用就会立即断开(因为弱引用指向的对象被垃圾回收了)

这时就会出现ThreadLocalMap中存在key为null的Entry

并且只要当前线程不结束,该ThreadLocalMap对象就会一直存在,无法回收(因为ThreadLocalMap还存在强引用:value本身就存着一个强引用对象)

此时就导致了内存泄露

既然会出现内存泄露为什么Entry的key还要使用弱引用?

为什么要用弱引用呢?

因为假设我们让key强引用ThreadLocal会导致该对象用永远无法gc

如何避免内存泄露?

其实ThreadLocalMap在设计时采取了一些措施来避免这种key为null、value不为null的对象占用内存

具体措施就是在我们调用ThreadLoca的set、get、remove方法时都会将这些key为null的对象清掉,避免因无法回收而导致内存泄露

如果没有及时使用remove方法会导致什么问题?

  1. 假设分配了ThreadLocal对象但是并没有执行get、set、remove方法会导致不能有效地清除null对象

  2. 因为ThreadLocal时属于某个线程的,而在使用线程池的情况下,这些线程都是可重复利用的、存活时间长的线程,因此不及时使用remove方法不仅会导致内存泄露问题,还会引发一些功能逻辑问题

    例如,B请求和A请求分配到了线程池中的同一个线程,那么他们拿到的ThreadLocal可能是一样的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/853973.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据分析案例《共享单车使用量综合分析案例》上新啦

《共享单车使用量综合分析案例》是一门数据分析和统计学的课程&#xff0c;旨在教学生如何综合运用数据分析技术&#xff0c;研究共享单车使用量的变化和影响因素&#xff0c;从真实的数据中探索有关共享单车使用量的问题&#xff0c;并通过数据挖掘、统计分析等方法&#xff0…

详解推送Git分支时发生的 cannot lock ref 错误

在码云上建了一个项目仓库,分支模型使用 git-flow ,并在本地新建了一个功能分支 feature/feature-poll。后来在推送时发生错误,提示 cannot lock ref ...... 这样的错误信息。下面复盘一下具体过程和解决办法,以供参考。 在码云中建立仓库时,考虑到想按照 GitFlow 的模式…

怎么把两个pdf合并成一个?这几种方法值得了解

怎么把两个pdf合并成一个&#xff1f;在日常工作中&#xff0c;我们经常需要合并两个或多个PDF文件成一个。但是&#xff0c;对于不熟悉PDF编辑器的人来说&#xff0c;这可能是一个棘手的问题。在本文中&#xff0c;我们将介绍一些合并PDF文件的方法&#xff0c;有需要的小伙伴…

音视频--视频数据传输

参考文献 H264码流RTP封装方式详解&#xff1a;https://blog.csdn.net/water1209/article/details/126019272H264视频传输、编解码----RTP协议对H264数据帧拆包、打包、解包过程&#xff1a; https://blog.csdn.net/wujian946110509/article/details/79129338H264之NALU解析&a…

【Leetcode】对称二叉树||递归(击败100%)

step by step. 题目&#xff1a; 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出…

lc2536.子矩阵元素加1

暴力解法&#xff1a;直接按照题目所示在矩阵的相应位置加一 时间复杂度&#xff1a;O(n2 * queries.length) 空间复杂度&#xff1a;O(1) 二维差分&#xff1a;创建二维差分数组&#xff0c;通过对差分数组的修改来影响原来的数组&#xff0c;最后还原 时间复杂度&#x…

FcaNet: Frequency Channel Attention Networks

FcaNet: Frequency Channel Attention Networks Abstract预备知识GAPDTC&#xff08;离散余弦变换&#xff09; 本文methodRevisiting DCT and Channel AttentionChannel Attention Multi-Spectral Channel AttentionMulti-Spectral Channel Attention ModuleCriteria for Choo…

超导材料LK-99烧制工艺中高真空度及其气氛环境控制的解决方案

摘要&#xff1a;根据近期LK-99超导材料研究报道&#xff0c;我们分析此材料制备采用了真空烧结工艺。由于目前大部分复现研究所用的真空烧结技术和设备都非常简陋&#xff0c;使得LK-99的复现性很差。为此我们提出了真空度准确控制解决方案&#xff0c;其目的第一是实现烧结初…

排序(快速排序,归并排序,插入排序,选择排序,冒泡排序,希尔排序,堆排序)

给定你一个长度为 n 的整数数列。 请你对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行&#xff0c;第一行包含整数 n 。 第二行包含 n 个整数&#xff08;所有整数均在 1∼109 范围内&#xff09;&#xff0c;表示整个数列。 输…

【深度学习MOT】SMILEtrack SiMIlarity LEarning for Multiple Object Tracking,论文

论文&#xff1a;https://arxiv.org/abs/2211.08824 文章目录 AbstractIntroduction2. 相关工作2.1 基于检测的跟踪2.1.1 检测方法2.1.2 数据关联方法 2.2 基于注意力的跟踪 3. 方法3.1 架构概述3.2 用于重新识别的相似性学习模块&#xff08;SLM&#xff09; Experimental Res…

【Docker晋升记】No.2 --- Docker工具安装使用、命令行选项及构建、共享和运行容器化应用程序

文章目录 前言&#x1f31f;一、Docker工具安装&#x1f31f;二、Docker命令行选项&#x1f30f;2.1.docker run命令选项&#xff1a;&#x1f30f;2.2.docker build命令选项&#xff1a;&#x1f30f;2.3.docker images命令选项&#xff1a;&#x1f30f;2.4.docker ps命令选项…

上篇文章viewerjs(npm包补丁)的错误更正。(npm补丁本地没问题,流水线打包要没效果,要么报错)

1、上篇文档的包补丁在本地使用没有问题&#xff0c;并且同事拉代码后也会自动同步npm_modules&#xff0c;也没有问题 2、问题出现在打包上&#xff0c;我这边的项目是用teambition上的飞流设置的流水线来进行打包的&#xff0c;里面用到了两个指令 yarn install npm run bu…

学习左耳听风栏目90天——第二天 2/90(学习左耳朵耗子的工匠精神,对技术的热爱)【程序员如何用技术变现(上)】

总结&#xff1a; 要去经历大多数人经历不到的&#xff0c;要把学习时间花在那些比较难的地方。要写文章就要写没有人写过的&#xff0c;或是别人写过&#xff0c;但我能写得更好的。更重要的是&#xff0c;技术和知识完全是可以变现的。学好英文&#xff0c;看技术文档 程序员…

解决idea编辑application.yml文件或properties文件没有提示问题

注意&#xff1a;这里说的没有提示&#xff0c;是针对application.properties和application.yml文件 解决办法&#xff1a;在idea的插件面板中&#xff0c;禁用或卸载 wl Spring Assistant插件即可解决问题。

python技术栈 之 单元测试中mock的使用

一、什么是mock&#xff1f; mock测试就是在测试过程中&#xff0c;对于某些不容易构造或者不容易获取的对象&#xff0c;用一个虚拟的对象来创建以便测试的测试方法。 二、mock的作用 特别是开发过程中上下游未完成的工序导致当前无法测试&#xff0c;需要虚拟某些特定对象…

Java基础入门篇——While循环(十二)

目录 一、循环结构语句 二、while循环语句 三、do-while循环语句 四、break使用 一、循环结构语句 在实际生活中经常会将同一件事情重复做很多次。例如&#xff0c;在做眼保健操的第四节轮刮眼眶时&#xff0c;会重复刮眼眶的动作&#xff1a;打乒乓球时&#xff0c;会重复…

npm ERR! code ERESOLVEnpm ERR! ERESOLVE unable to resolve dependency tree

拉取项目到本地 执行 npm install 报错 遇到这个问题首先确认的就是版本是不是太高了&#xff0c;降一下版本。或者通过yarn命令替代npm install命令安装&#xff0c;同理&#xff0c;启动也可以采用yarn dev 启动代替npm run dev 下面教大家用一个NVM工具&#xff0c;这个工…

Linux基础与应用开发系列七:一切皆文件

Linux内核 屏蔽硬件区别&#xff0c;把所有的硬件设备抽象成文件&#xff0c;提供统一的接口给用户使用。 虚拟文件系统 抽象层&#xff0c;对文件的访问实际上使对抽象层的访问。 抽象对象&#xff1a;封装了底层读写细节&#xff0c;使用c语言的多态来实现具体文件系统系统…

乐鑫首创|使用 ESP RainMaker® 私有云定制 Matter 生态

ESP RainMaker 是乐鑫的 AIoT 云平台&#xff0c;支持客户自主部署私有物联网云&#xff0c;从而全面掌握数据所有权和管理权&#xff0c;实现定制功能与服务。ESP RainMaker 云后端采用 AWS 无服务器架构&#xff0c;拥有开源的 iOS 和 Android 移动端 APP、第三方语音助手集成…

Java—IO 流

Java—IO 流 &#x1f50d;文件创建文件获取文件相关信息目录相关操作 &#x1f50d;IO 流理解流与文件流的分类FileInputStreamFileOutputStream文件拷贝FileReaderFileWriter节点流与处理流类型 BufferedReaderBufferedWriterBufferedInputStream BufferedOutputStream对象处…