当前位置: 首页 > news >正文

java ThreadLocal

private ThreadLocal threadLocal = new ThreadLocal();
threadLocal.set(0);
(int) threadLocal.get();

上面三行代码分别是定义、赋值和取值。

介绍:

我们只需要实例化对象一次,并且也不需要知道它是被哪个线程实例化。虽然所有的线程都能访问到这个ThreadLocal实例,但是每个线程却只能访问到自己通过调用ThreadLocal的set()方法设置的值。即使是两个不同的线程在同一个ThreadLocal对象上设置了不同的值,他们仍然无法访问到对方的值。

需要框架源码的朋友可以看我个人简介联系我,推荐分布式架构源码。 

各个线程赋值读取互补干扰的原理:

源码中有一个ThreadLoalMap类型的东西,理解成map类型即可。

详解一下取值过程,调用ThreadLocal的get方法时,会先调用getMap(t)获取到ThreadLoalMap的集合,其中参数t为当前线程(Thread.currentThread()),getMap方法表示每个线程对象中都维护有这么个ThreadLoalMap对象集合。

public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();
}
ThreadLocalMap getMap(Thread t) {return t.threadLocals;
}

然后,调用该集合的getEntry方法,参数就是ThreadLocal对象本身,ThreadLocal的hash值和table.length构成了Entry的键。

private Entry getEntry(ThreadLocal<?> key) {int i = key.threadLocalHashCode & (table.length - 1);Entry e = table[i];if (e != null && e.get() == key)return e;elsereturn getEntryAfterMiss(key, i, e);
}

总结下:

每个线程都维护有一个ThreadLocalMap对象集合,他的键就是ThreadLocal对象的hash(相当于这么个东西),这样A、B两个线程就会各自维护一个ThreadLocalMap对象集合,共用一个ThreadLocal对象的hash值当作其中的键,就相当于A线程的ThreadLocalMap有共用的hash键,B线程的ThreadLocalMap也有一个共用的hash键。这样就不会冲突了,有点绕,多查资料多理解。

InheritableThreadLocal其中还有这么个东西,InheritableThreadLocal类是ThreadLocal类的子类。ThreadLocal中每个线程拥有它自己的值,与ThreadLocal不同的是,InheritableThreadLocal允许一个线程以及该线程创建的所有子线程都可以访问它保存的值。相当于一个类定义成protected。

1. 每个Thread实例内部,有二个ThreadLocalMap的K-V容器实例(分别对应threadLocals及inheritableThreadLocals), 容器的元素数量,即为Thread实例里的ThreadLocal实例个数
2. ThreadLocalMap里的每个Entry的Key与ThreadLocal实例的HashCode相关(这样,多个ThreadLocal实例就不会搞混)
3. 每个ThreadLocal实例使用set赋值时,实际上是在ThreadLocalMap容器里,添加(或更新)一条Entry信息
4. 每个ThreadLocal实例使用get取值时,从ThreadLocalMap里根据key取出value 。

关于内存泄漏问题:

通过之前的分析已经知道,当使用ThreadLocal保存一个value时,会在ThreadLocalMap中的数组插入一个Entry对象,按理说key-value都应该以强引用保存在Entry对象中,但在ThreadLocalMap的实现中,key被保存到了WeakReference对象中,源码中是继承WeakReference对象了。

static class Entry extends WeakReference<ThreadLocal<?>>

ThreadLocal在ThreadLocalMap中是以一个弱引用身份被Entry中的Key引用的,因此如果ThreadLocal没有外部强引用来引用它,那么ThreadLocal会在下次JVM垃圾收集时被回收。这个时候就会出现Entry中Key已经被回收,出现一个null Key的情况,外部读取ThreadLocalMap中的元素是无法通过null Key来找到Value的。因此如果当前线程的生命周期很长,一直存在,那么其内部的ThreadLocalMap对象也一直生存下来,这些null key就存在一条强引用链的关系一直存在:Thread --> ThreadLocalMap-->Entry-->Value,这条强引用链会导致Entry不会回收,Value也不会回收,但Entry中的Key却已经被回收的情况,造成内存泄漏。

但是JVM团队已经考虑到这样的情况,并做了一些措施来保证ThreadLocal尽量不会内存泄漏:在ThreadLocal的get()、set()、remove()方法调用的时候会清除掉线程ThreadLocalMap中所有Entry中Key为null的Value,并将整个Entry设置为null,利于下次内存回收。

相关文章:

java ThreadLocal

private ThreadLocal threadLocal new ThreadLocal(); threadLocal.set(0); (int) threadLocal.get(); 上面三行代码分别是定义、赋值和取值。 介绍&#xff1a; 我们只需要实例化对象一次&#xff0c;并且也不需要知道它是被哪个线程实例化。虽然所有的线程都能访问到这个T…...

MySQL高级篇第6章(索引的数据结构)

文章目录 1、为什么使用索引2、索引及其优缺点3、InnoDB中索引的推演4、MyISAM中的索引方案5、索引的代价6、MySQL数据结构选择的合理性 1、为什么使用索引 假如给数据使用 二叉树 这样的数据结构进行存储&#xff0c;如下图所示 2、索引及其优缺点 3、InnoDB中索引的推演 4、M…...

Unity 性能优化三:动画模块、物理模块

目录 动画模块 Mecanim 模块 1.1 Animator active的数量 1.1.1 Culling Mode 1.1.2 Optimize Gameobject 1.1.3 Apply Root Motion 1.1.4 Compute Skinning 1.1.5 Animator Initialize 1.2 Legacy动画 物理模块 2.1 物理更新次数 2.1 减少不必要的Collision 2.5 A…...

延迟函数

Destory函数&#xff1a; public static void Destroy(Object obj, [DefaultValue("0.0F")] float t); Invoke函数&#xff1a; public void Invoke(string methodName, float time); 挂个空物体测试一下&#xff1a; public class DelayTest : MonoBehaviour {…...

IBM报告:2023数据泄露平均成本将达到445万美元

7月24日&#xff0c;IBM发布年度《数据泄露成本报告》显示&#xff0c;2023年全球数据泄露的平均成本达到445万美元&#xff0c;创该报告有史以来最高纪录&#xff0c;较过去3年均值增长了15&#xff05;。同一时期&#xff0c;检测安全漏洞和漏洞恶化带来的安全成本上升了42&a…...

20.3 HTML 表格

1. table表格 table标签是HTML中用来创建表格的元素. table标签通常包含以下子标签: - th标签: 表示表格的表头单元格(table header), 用于描述列的标题. - tr标签: 表示表格的行(table row). - td标签: 表示表格的单元格(table data), 通常位于tr标签内, 用于放置单元格中的…...

flutter项目运行时一直卡在Running Gradle task ‘assembleDebug‘解决办法

1.修改项目中的android/build.gradle&#xff0c;将google()&#xff0c;mavenCentral()替换为下面的代码 maven { url https://maven.aliyun.com/repository/central/ }maven { url https://maven.aliyun.com/repository/public/ }maven { url https://maven.aliyun.com/repos…...

“深入理解Spring Boot:从入门到精通“

标题&#xff1a;深入理解Spring Boot&#xff1a;从入门到精通 摘要&#xff1a; Spring Boot是一款用于简化Spring应用开发的框架&#xff0c;它提供了一系列的开箱即用的功能和自动化配置&#xff0c;使得开发者能够快速构建、部署和运行Spring应用。本文将从入门到精通&am…...

IP 工具

什么是IP 工具 IP 工具是用于轻松扫描和排除网络 IP 地址空间故障的网络工程工具。IP 工具使网络管理员能够审核、跟踪和监视 IP 地址、子网以及使用 IP 的设备和主机的性能。这个全面的网络工程工具集包括高级 IP 工具&#xff0c;如 Ping、系统资源管理器、MAC 地址解析器和…...

Linux - 进程概念(进程状态、优先级)

1.进程状态 操作系统中进程有多种状态模型 三态模型 进程状态分为 就绪态&#xff0c;执行态&#xff0c;阻塞态。 就绪(Ready)状态&#xff1a;指进程已处于准备好运行的状态&#xff0c;即进程已分配到除CPU以外的所有必要资源后&#xff0c;只要再获得CPU&#xff0c;便可立…...

k8s概念-deployment

deployment用于部署无状态应用 Deployment集成了上线部署、滚动升级、创建副本、回滚等功能 Deployment里包含并使用了ReplicaSet Replicaset 通过改变Pod副本数量实现Pod的扩容和缩容 参考文档 https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/ …...

Flutter 调试工具篇 | 壹 - 使用 Flutter Inspector 分析界面

theme: cyanosis 1. 前言 很多朋友可能在布局过程中、或者组件使用过程中&#xff0c;会遇到诸如颜色、尺寸、约束、定位等问题&#xff0c;可能会让你抓耳挠腮。俗话说&#xff0c;磨刀不误砍柴工&#xff0c;会使用工具是非常重要的&#xff0c;其实 Flutter 提供了强大的调试…...

什么是云原生和 CNCF?

一、CNCF简介 CNCF&#xff1a;全称Cloud Native Computing Foundation&#xff08;云原生计算基金会&#xff09;&#xff0c;成立于 2015 年 12 月 11 日&#xff0c;是一个开源软件基金会&#xff0c;它致力于云原生&#xff08;Cloud Native&#xff09;技术的普及和可持续…...

数据结构——单链表

无头单向非循环链表的建立 前言——什么链表链表形象图链表分类 一、Single_linked_list.h头文件的建立二、Single_linked_list.c功能函数的定义Single_linked_list_test.c主函数的定义四、代码运行测试五、Single_linked_list完整代码演示&#xff1a;总结 前言——什么链表 链…...

微信小程序手写签字版

在这里插入图片描述 wxml 请在下面的白框中签名 重置 提交 # js Page({ data: { signPath: [], cardNo: , preX: , preY: , }, onLoad(options) { this.setData({ cardNo: options.cardNo }) wx.createSelectorQuery().select(#myCanvas).fields({ node: true, size: true }).…...

机器学习十大经典算法

机器学习算法是计算机科学和人工智能领域的关键组成部分&#xff0c;它们用于从数据中学习模式并作出预测或做出决策。本文将为大家介绍十大经典机器学习算法&#xff0c;其中包括了线性回归、逻辑回归、支持向量机、朴素贝叶斯、决策树等算法&#xff0c;每种算法都在特定的领…...

HCIP-datacom-821题库真题和机构资料

HCIP-Datacom-Core Technology考试内容 HCIP-Datacom-Core Technology V1.0考试覆盖数据通信领域各场景通用核心知识&#xff0c;包括路由基础、OSPF、IS-IS、BGP、路由和流量控制、以太网交换技术、组播、IPv6、网络安全、网络可靠性、网络服务与管理、WLAN、网络解决方案。 机…...

javaSE,javaEE,javaME的区别

1. JavaSE&#xff08;Java Platform&#xff0c;Standard Edition&#xff0c;又称J2SE&#xff09;&#xff0c;可以理解为Java标准版本 这个版本的jdk通常包含了Java日常开发使用的基本类&#xff0c;允许开发和部署在桌面、服务器、嵌入式环境和实时环境中中使用&#xff0…...

mysql innodb一些知识点

1、事务和锁的关系&#xff1b; 在MySQL事务中&#xff0c;只要开始了一次事务&#xff0c;就会自动加上一个共享锁&#xff08;Shared Lock&#xff09;。这个锁会在事务结束时自动释放。如果在事务中需要更新某个数据对象&#xff0c;那么MySQL会将该数据对象的共享锁升级为…...

Android 面试题 应用对内存是如何限制 八

&#x1f525; OutOfMemeryError的原因 &#x1f525; Android 针对每个应用有内存限制 , 当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时&#xff0c;就会抛出这个error&#xff08;注&#xff1a;非exception&#xff0c;因为这个问题已经严…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...