ThreadLLocal的学习

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.mzph.cn/news/33508.shtml

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

相关文章

最新版本2023UI千月影视APP源码 开源完美版前后端完美匹配 后端基于ThinkPHP框架

最新版本的2023UI千月影视APP源码是一款开源的完美版应用程序&#xff0c;具备前后端完美匹配的特点。该应用的后端开发基于ThinkPHP框架&#xff0c;这是一个广泛使用的PHP开发框架&#xff0c;具有稳定性和安全性方面的优势。 2023UI千月影视APP是一款提供电影、电视剧、综艺…

Clickhouse学习系列——一条SQL完成gourp by分组与不分组数值计算

笔者在近一两年接触了Clickhouse数据库&#xff0c;在项目中也进行了一些实践&#xff0c;但一直都没有一些技术文章的沉淀&#xff0c;近期打算做个系列&#xff0c;通过一些具体的场景将Clickhouse的用法进行沉淀和分享&#xff0c;供大家参考。 首先我们假设一个Clickhouse数…

智能合约 -- 常规漏洞分析 + 实例

1.重入攻击 漏洞分析 攻击者利用合约漏洞&#xff0c;通过fallback()或者receive()函数进行函数递归进行持续取钱。 刚才试了一下可以递归10次&#xff0c;貌似就结束了(version: 0.8.20)。 直接看代码: 银行合约&#xff1a;有存钱、取钱、查看账户余额等函数。攻击合约:…

第04天 Spring是如何解决循环依赖的

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…

【VUE】7、VUE项目中集成watermark实现页面添加水印

在网站浏览中&#xff0c;常常需要网页水印&#xff0c;以便防止用户截图或录屏暴露敏感信息后&#xff0c;方便追踪用户来源。 1、安装 watermark 在 package.json 文件 dependencies 节点增加 watermark-dom 依赖 "watermark-dom": "2.3.0"然后执行命…

Petrel解释二维浅地层数据

Petrel是斯伦贝谢开发的一款地质解释和建模软件&#xff0c;有点像地理信息系统的ArcGIS&#xff0c;主要用于数据分析和展示。它不是用来处理原始数据的&#xff0c;而是集成各种处理后的结果数据进行特征分析和目标拾取。当然&#xff0c;它也能读取原始数据&#xff0c;比如…

Vue 3.0中的Treeshaking?

1.treeshaking是什么&#xff1f; Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术&#xff0c;专业术语叫 Dead code elimination 简单来讲&#xff0c;就是在保持代码运行结果不变的前提下&#xff0c;去除无用的代码 如果把代码打包比作制作蛋糕&#…

5. 服务发现

当主机较少时&#xff0c;在抓取配置中手动列出它们的IP地址和端口是常见的做法&#xff0c;但不适用于较大规模的集群。尤其不适用使用容器和基于云的实例的动态集群&#xff0c;这些实例经常会变化、创建或销毁的情况。 Prometheus通过使用服务发现解决了这个问题&#xff1…

EFLFK——ELK日志分析系统+kafka+filebeat架构(3)

zookeeperkafka分布式消息队列集群的部署 紧接上期&#xff0c;在ELFK的基础上&#xff0c;添加kafka做数据缓冲 附kafka消息队列 nginx服务器配置filebeat收集日志&#xff1a;192.168.116.40&#xff0c;修改配置将采集到的日志转发给kafka&#xff1b; kafka集群&#xff…

(5)所有角色数据分析页面的构建-5

所有角色数据分析页面&#xff0c;包括一个时间轴柱状图、六个散点图、六个柱状图(每个属性角色的生命值/防御力/攻击力的max与min的对比)。 """绘图""" from pyecharts.charts import Timeline from find_type import FindType import pandas …

RN 使用react-navigation写可以滚动的横向导航条(expo项目)

装包&#xff1a; yarn add react-navigation/material-top-tabs react-native-tab-view npx expo install react-native-pager-view import React from react import { View, Text, ScrollView, SafeAreaView } from react-native import { Icon } from ../../../../../compo…

栈和队列详解

目录 栈 栈的概念及结构&#xff1a; 栈的实现&#xff1a; 代码实现&#xff1a; Stack.h stack.c 队列&#xff1a; 概念及结构&#xff1a; 队列的实现&#xff1a; 代码实现&#xff1a; Queue.h Queue.c 拓展&#xff1a; 循环队列&#xff08;LeetCode题目链接&#xff0…

机器学习基础08-回归算法矩阵分析(基于波士顿房价(Boston House Price)数据集)

回归算法通常涉及到使用矩阵来表示数据和模型参数。线性回归是最常见的回归算法之一&#xff0c;它可以用矩阵形式来表示。 考虑一个简单的线性回归模型&#xff1a; y m x b y mx b ymxb&#xff0c;其中 y y y 是因变量&#xff0c; x x x 是自变量&#xff0c; m m m 是…

美团视觉GPU推理服务部署架构优化实战

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

【C++】开源:tinyxml2解析库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍tinyxml2解析库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;…

【问题解决】Git命令行常见error及其解决方法

以下是我一段时间没有使用xshell&#xff0c;然后用git命令行遇到的一些系列错误和他们的解决方法 遇到了这个报错&#xff1a; fatal: Not a git repository (or any of the parent directories): .git 我查阅一些博客和资料&#xff0c;可以解决的方式&#xff1a; git in…

冒泡排序 简单选择排序 插入排序 快速排序

bubblesort 两个for循环&#xff0c;从最右端开始一个一个逐渐有序 #include <stdio.h> #include <string.h> #include <stdlib.h>void bubble(int *arr, int len); int main(int argc, char *argv[]) {int arr[] {1, 2, 3, 4, 5, 6, 7};int len sizeof(…

学习Linux,要把握哪些重点?

不知道有没有想学习Linux&#xff0c;但又把握不住学习重点&#xff0c;找不到合适的学习方法的小伙伴&#xff0c;反正我刚开始学习Linux时就像无头苍蝇似的“乱撞”&#xff0c;没有把握住学习重点&#xff0c;不知道怎么去学&#xff0c;差点要放弃了&#xff0c;还好在慢慢…

栈和队列详解(1)

目录 一、什么是栈&#xff1f; 二、创建一个我们自己的栈 1.前置准备 1.1需要的三个文件 1.2结构体的创建和头文件的引用 2.接口的实现 2.1初始化栈结构体 2.2尾插(压栈) 2.3栈存放的元素个数和判断栈是否为空 2.4获取栈顶元素 2.5出栈 2.6摧毁栈 2.7测试接口 三、…

【Freertos基础入门】freertos任务的优先级

文章目录 前言一、任务优先级1.Tick2.修改任务优先级 总结 前言 本系列基于stm32系列单片机来使用freerots 任务管理是实时操作系统&#xff08;RTOS&#xff09;的核心功能之一&#xff0c;它允许开发者以并发的方式组织和管理多个任务。FreeRTOS 是一个流行的开源RTOS&…