ThreadLocal底层原理

news2024/7/6 19:26:49

ThreadLocal底层原理

  • 一:什么是ThreadLocal
  • 二:理解ThreadLocal中的内存泄漏问题
  • 三:ThreadLocalMap中的Hash冲突处理
  • 四:可以被继承的ThreadLocal——InheritableThreadLocal

一:什么是ThreadLocal

ThreadLocal是一个创建线程局部变量的类,ThreadLocal中的变量只有当前自身线程可以访问,别的线程都访问不了。

实现原理:
每一个线程都有一个对应的Thread对象,而Thread类有一个ThreadLocalMap类型变量(threadLocals)和一个内部类ThreadLocal。这个threadLocals的key就是ThreadLocal的引用,而value就是当前线程在key所对应的ThreadLocal中存储的值。当某个线程需要获取存储在自己线程Thread的ThreadLocal变量中的值时,ThreadLocal底层会获取当前线程的Thread对象中的Map集合threadLocals,然后以ThreadLocal作为key,从threadLocals中查找value值。这就是ThreadLocal实现线程独立的原理。
在这里插入图片描述
为什么用Entry数组而不是Entry对象?
因为在业务代码中能new好多个ThreadLocal对象,各司其职。但是在一次请求里,也就是一个线程里,ThreadLocalMap是同一个,而不是多个。不管你new几次ThreadLocal,ThreadLocalMap在一个线程里就一个,因为ThreadLocalMap的引用是在Thread里的。所以它里面的Entry数组存放的是一个线程里你new出来的多个ThreadLocal对象。

二:理解ThreadLocal中的内存泄漏问题

ThreadLocal.ThreadLocalMap是一个比较特殊的Map,它的每个Entry的key都是一个弱引用。
这样设计的好处是,如果这个变量不再被其他对象使用时,可以自动回收这个ThreadLocal对象,避免可能的内存泄露。

注意:Entry中的value,依然是强引用。
在这里插入图片描述
ThreadLocalMap中的key是弱引用,当不存在外部强引用的时候,就会自动被回收。但是Entry中的value依然是强引用。这个value的引用链条如下:
在这里插入图片描述
可以看到,只有当Thread被回收时,这个value才有被回收的机会。否则,只要线程不退出,value总是会存在一个强引用。但是,要求每个Thread都会退出,是一个极其苛刻的要求。对于线程池来说,大部分线程会一直存在在系统的整个生命周期内,那样的话,就会造成value对象出现泄漏的可能。处理的方法是,当你不需要这个ThreadLocal变量时,主动调用remove(),这样对整个系统是有好处的。

/**
 * 将当前线程局部变量的值删除,目的是为了减少内存占用。主要目的是防止内存泄漏。
 */
public void remove() {
    // 获取当前线程的ThreadLocalMap对象,并将其移除。
    ThreadLocalMap m = getMap(Thread.currentThread());
    if (m != null)
        // 直接移除以当前ThreadLocal为key的value
        m.remove(this);
}

三:ThreadLocalMap中的Hash冲突处理

ThreadLocalMap作为一个HashMap和java.util.HashMap的实现是不同的。对于java.util.HashMap使用的是链表法来处理冲突:
在这里插入图片描述
但是,对于ThreadLocalMap,它使用的是简单的线性探测法,如果发生了元素冲突,那么就使用下一个槽位存放:
在这里插入图片描述

四:可以被继承的ThreadLocal——InheritableThreadLocal

ThreadLocal真的只是当前线程可见吗?

在实际开发过程中,我们可能会遇到这么一种场景。主线程开了一个子线程,但是我们希望在子线程中可以访问主线程中的ThreadLocal对象,也就是说有些数据需要进行父子线程间的传递。

因为在子线程中,是没有threadLocal的。如果我们希望子线可以看到父线程的ThreadLocal,那么就可以使用InheritableThreadLocal。顾名思义,这就是一个支持线程间父子继承的ThreadLocal。

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

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

相关文章

【电脑故障】PIN无效,显示无用户配置文件

【电脑故障】PIN无效。显示无用户配置文件1. 电脑情况:2. 解决方法(个人):2.1 解决登录问题2.2 解决PIN可用设置1. 电脑情况: 电脑品牌:联想小新pro13操作系统:win10 2. 解决方法(…

C++初阶--stack和queue

目录 stack介绍 stack的使用 stack的模拟实现 queue的介绍 queue的使用 queue的模拟实现 deque priority_queue priority_queue的使用 仿函数 priority_queue的模拟实现 stack介绍: stack是一种容器适配器,专门用在具有后进先出操作的上下文环…

Nginx使用(三)配置实例

一、反向代理示例一效果:打开浏览器,在浏览器地址栏输入地址www.123.com,跳转到linux系统tomcat主页面中具体实现:(1) 准备:安装nginx在linux系统安装tomcat,使用默认端口8080解压之后进入到tom…

一篇文章读懂mybatis-plus原理和CRUD接口

Myabtis-Plus配置 MybatisPlus官网 官方文档上有详细的spring boot配置mybatis-plus的教程&#xff0c;此处就不在详细赘述。 mybatis-plus是基于spring完成的只能再spring相关应用上实现。 引入父工程 注意mybatis-plus和spring boot的版本匹配不然会出现 推荐版本 <pa…

自媒体神器 Previs Shot 使用指南

Previs Shot 是一款影视创作的项目管理工具&#xff0c;更高效的方式开始您的影视创作历程。分镜表分镜表可高效绘制画面、编写景别、运镜、内容、台词等&#xff0c;甚至可以填写摄影器材、灯光等信息。分镜结构场景&#xff1a;电影里比如过生日、开party都是不同的场景&…

【程序员陪你过大年】html+css+js 实现动态新年烟花特效及服务器部署

前言 不知不觉又到了年底&#xff0c;这一年是值得庆贺的一年&#xff0c;疫情过去&#xff0c;经济好转。我们急需在春节这个特殊的日志释放下自己的情绪。但是大部分地区都不让放炮&#xff0c;于是乎我为大家带来一套十分炫酷应景的春节烟花动画代码实现。效果如下图所示 :…

【如何在Linux下使用Git命令在Gitee上创建项目】

目录 1 创建仓库 2 Git提交三板斧 2.1 add 2.2 commit 2.3 push 1 创建仓库 首先我们可以使用命令&#xff1a;git --version 来查看是否下在了git,没有下载的可以使用下面的命令安装&#xff1a; sudo yum install -y git 成功后就可以查看了&#xff1a; [grmVM-8-12-…

深度学习目标检测_YOLOV3超详细解读

文章目录YOLO V3概述网络结构backbone&#xff1a;darknet-53特征细化&#xff08;多scale&#xff09;残差连接残差网络的发家史先验框softmax改进YOLO V3概述 yolo v3论文地址&#xff1a;https://pjreddie.com/media/files/papers/YOLOv3.pdf 先说说yolo v3的效果&#xff…

字节青训营Go语言学习第二天-Go语言进阶与依赖管理

文章目录并行VS并发GoroutineCSPChannel并发安全LockWithGroupGo依赖管理GoPathGo VendorGo Module依赖分发-回源并行VS并发 并发指的是多线程在一个CPU上运行&#xff0c;而并行是直利用多核来实现多线程。 内核是系统里比较昂贵的系统资源&#xff0c;它的创建、切换停止都是…

K8s可视化界面Kubernetes DashboardKuboard

目录一、简介二、Kubernetes Dashboard2.1 部署dashboard2.2 访问UI2.3 创建访问账号三、Kuboard3.1 部署2.2 访问UI一、简介 本文给大家介绍两个K8s集群的可视化工具 Kubernetes Dashboard 和 Kuboard 二、Kubernetes Dashboard 2.1 部署dashboard dashboard Github地址&a…

【算法基础(2)】二分查找和斐波那契数列

二分查找 二分查找高效的前提是数据结构是有序的 思路&#xff1a; 1.排序 2.将数组折半&#xff0c;分成左右两个数组。 3.判断要查找的数和中间位置数值的大小&#xff0c;来判断要查找的数实在哪一半。 4.之后继续折半查找&#xff0c;直至找到这个数。 图解&#xff1a; 首…

SpringMVC看这一篇文章就够了

第一章 SpringMVC的简介 Spring框架版本 4.3.29.RELEASE SpringMVC是什么 1 2 3 4 5 61. Spring家族的一个部分 2. 是JavaWeb三层架构中控制器层的解决方案 3. 是基于MVC思想的框架-- Model-- View-- ControllerSpringMVC知识点大纲SpringMVC功能简述 1 2 3 4 5 6 7 8 9 101. 作…

WEB前端有必要学会docker吗?0基础-45分钟带你学会(包含视频笔记案例源代码)

文章目录一、为什么要使用docker二、Windows10/11系统安装Docker Desktop三、如何判断电脑已经安装好docker四、docker前端应用实战&#xff1a;将vue项目打包为docker镜像运行1、将vue的项目进行构建&#xff0c;输出dist2、准备镜像内容3、制作镜像4、启动镜像五、如何发布镜…

【Leetcode】面试题 01.02. 判定是否互为字符重排、面试题 01.04. 回文排列

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 面试题 01.02. 判定是否互为字符重排 面试题 01.04. 回文排列 面试题 …

水果店做微信活动推荐_分享水果店微信小程序制作步骤

试试做个小程序拯救你的店&#xff01;让你做出有效果的活动&#xff0c;每笔钱都花在刀刃上&#xff01;编辑第一&#xff0c;提升水果销量&#xff0c;降低损耗用水果店小程序做拼团、砍价、秒杀活动&#xff0c;并讲原本卖不完的水果&#xff0c;做成果盘吸引客人注册会员。…

点成分享|关于Grant水浴的一些FAQ

1、关于稳定性和均匀性 1&#xff09;稳定性&#xff0c;是水浴中任何一点在达到恒温时不同时间下的温度规律性波动程度的描述&#xff0c;是通过浴槽中心点测定的&#xff0c;并表示为测量值的正负一半。系同点不同时的温度特性描述。 例如&#xff1a;SAP恒温水浴设定温度为…

unreal engine建模模式建模研究

Create PolyExt 挤出(需要闭合) image.pngPathExt 具有宽度挤出 (无需闭合) 如下图绘制一个形状后按鼠标左键确定绘制完成再移动鼠标控制厚度按鼠标左键确定后端后再移动鼠标确定高度 image.pngimage.pngPathRev Draw and revolve polypaths to create new objects 画和旋转pol…

企业级监控项目Skywalking详细介绍,来看看呀

一. Skywalking概述一个优秀的项目&#xff0c;除了具有高拓展的架构、高性能的方案、高质量的代码之外&#xff0c;还应该在上线后具备多角度的监控功能。现在企业中的监控服务也有很多&#xff0c;Skywalking除了提供多维度、多粒度的监控之外&#xff0c;也提供了良好的图形…

Kotlin 元编程之 KSP 全面突破

什么是元编程 没想到吧&#xff0c;这世上除了元宇宙&#xff0c;还有元编程&#xff0c;如果没有接触过&#xff0c;可能会有点懵&#xff0c;不过没关系&#xff0c;简单的说就是用代码来生成代码。实现元编程的传统常见手段主要是使用 APT注解处理器 JavaPoet 组合拳&…

JAVA基础知识巩固训练

目录 1. 案例一&#xff1a;逢 7 跳过 2. 案例二&#xff1a;数组元素求和 3. 案例三&#xff1a;判断两个数组是否相同⭐ 4. 案例四&#xff1a;查找元素在数组中的索引 5. 案例五&#xff1a;数组元素反转 6. 案例六&#xff1a;评委打分 7. 案例七&#xff1a;随机产…