ThreadLocal线程局部变量

news2024/11/25 20:35:48

1.原理

        ThreadLocal是用来保存当前线程数据的,每一个线程的内部都有一个ThreadLocalMap,当前这个map中存储了以当前ThreadLocal,具体的数据的一个个Entry对象。

                

        为什么非得以ThreadLocal对象作键呢?因为一个线程可能使用了不止一个ThreadLocal对象,如果以当前线程对象做键,再去找对应的ThreadLocal就很麻烦,产生混淆。

        由于每一个线程都有属于自己的ThreadLocal线程局部变量,所以很好的实现了线程之间的数据隔离ThreadLocal中保存的数据仅属于当前线程)。       

2.ThreadLocal中的常见方法:

        (1)存储数据        set()

        (2)获取数据        get()

        (3)清除数据         remove()

        那么问题来了,具体是怎样利用ThreadLocalMap查找数据的呢?不论是set()、get()、remove()等方法对当前map进行操作时,最终都定位到了通过计算出的下标来操作。

        而这个下标是通过哈希算法计算得到的,操作ThreadLocalMap是以当前的ThreadLocal作key,通过当前的key的HashCode值和Entry[]数组长度-1“&”运算,来计算出实际操作位置的下标,从而达到访问元素的目的。        

        作按位与运算的效果和利用哈希值直接进行取余%运算一样,但效率大大提高

3.如何实现父子线程共享数据?

        利用了jdk提供ThreadLocal的子类InheritableThreadLocal来实现。

public class ThreadLocalTest {

    public static void main(String[] args) {
    	InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<String>();
		threadLocal.set("风萧萧兮易水寒");
		System.out.println("main主线程:"+threadLocal.get());
		
		Thread thread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("子线程:"+threadLocal.get());
			}
		});
		thread.start();
    }
}

        main函数为父线程,创建了一个thread子线程,利用InheritableThreadLocal这个子类来共享父线程的数据。

        父线程子线程均输出“风萧萧兮易水寒”。

4.ThreadLocal如何避免内存泄露

        执行完相关的业务逻辑后,最终在finally代码块中都会调用remove()方法,将当前map中的ThreadLocal键置为空,value置为空,从而在垃圾回收的时候及时回收无用数据。

5.应用

        (1) 线程的数据隔离

        因为ThreadLocal对象只属于当前线程,那么ThreadLocal中的数据也属于当前线程,在多线程并发的情况下,很好的实现了不同线程的数据隔离,避免了采用synchronized锁机制来保证线程安全而导致的性能上的代价。

        例如:SqlSession会话对象绑定,避免多个线程使用同一个SqlSession对象,由于关闭导致异常。

//当前线程的线程局部变量
private static final ThreadLocal threadSession= new ThreadLocal();

public static SqlSession getSession(){//获取session会话方法
    SqlSession s = (SqlSession)threadSession.get();//通过仅属于当前线程的threadSession对象来获取
    if(s==null){//为空
        s = getSqlSessionFactory().openSqlSession();//则重新建立会话
        threadSession.set(s);//并存到ThreadLocalMap中去
    }
}

        (2)跨函数调用

        数据通常用于同一个类中的传递,如果利用方法传递势必要关心方法的返回值类型及参数,但利用ThreadLocal可以直接实现获取,这样做还达到了解耦的效果。

        例如:RequestContextHolder源码就有很好的体现

@Nullable  
public static RequestAttributes getRequestAttributes() {
    // 获取当前线程中的存储的Request Attribute
    //直接通过ThreadLocal对象来获取
    RequestAttributes attributes = requestAttributesHolder.get();  
    if (attributes == null) {  
        attributes = inheritableRequestAttributesHolder.get();  
    }  
    return attributes;  
}

private static final ThreadLocal<RequestAttributes> requestAttributesHolder =  new NamedThreadLocal<>("Request attributes");  
  
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =  new NamedInheritableThreadLocal<>("Request context");

以上就是我对ThreadLocal线程区域对象的粗略理解,欢迎诸君共同探讨。

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

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

相关文章

手游联运平台是什么?

手游联运平台是一种服务于手游联运的专业平台&#xff0c;旨在为游戏开发商、发行商和代理商提供联运合作所需的技术、工具和资源。这些平台通常提供以下功能和服务&#xff1a; 游戏接入和管理&#xff1a;允许游戏开发商将他们的游戏接入联运平台&#xff0c;以便发行到不同的…

linux 环境变量详解/etc/proflie

Linux 环境变量是可以在多个文件中进行配置的&#xff0c;如/etc/proflie&#xff0c;/etc/profile.d/*.sh&#xff0c;~/.bashrc&#xff0c;~/.bash_profile等但是这些之间有什么区别呢 bash的运行模式可以分为 login shell 和 non-login shell。 例如&#xff1a;通过终端&a…

【送书活动】强势挑战Java,Kotlin杀回TIOBE榜单Top 20!学Kotlin看哪些书?

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

王道考研操作系统

王道考研操作系统 计算机系统概述操作系统的概念操作系统的特征操作系统的发展历程操作系统内核中断和异常![在这里插入图片描述](https://img-blog.csdnimg.cn/162452b4c60144e0bd500e180127c447.png)系统调用操作系统结构虚拟机错题 进程与线程进程控制进程通信线程和多线程模…

Python+Selenium定位不到元素常见原因及解决办法(报:NoSuchElementException)

这篇文章主要介绍了PythonSelenium定位不到元素常见原因及解决办法(报&#xff1a;NoSuchElementException),文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 在做web应用的自动…

elasticsearch17-自动补全

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…

2023/9/17总结

Vue defineOptions 为什么要使用defineOptions 在有<script setup> 之前 如果需要定义props emit 可以很容易的添加一个与setup 平级的属性 但是用了 <script setup> 后 就不能这样做了 setup 属性也就没有了&#xff0c;就不能添加 与其平级 的属性 为了解…

基于springboot+vue的网上商城系统

一、选题背景意义 &#x1f30a;项目背景&#xff1a;该电子商城系统旨在为商家和消费者提供一个直观、易用的购物平台&#xff0c;通过该平台销售商品和宣传品牌&#xff0c;消费者通过该平台购买商品&#xff0c;享受更便捷的购物体验。在该电子商城系统中&#xff0c;商家可…

腾讯Behaviac Designer 和Unity连调行为树

1. 克隆源码 https://github.com/Tencent/behaviac/ 2. 编译生成BehaviacDesigner.exe 3. 找到并打开BehaviacDesigner.exe&#xff08;先不急着填弹出的路径workspace 设置框&#xff09; 4. 新建一个Unity 空工程&#xff0c;并在此处下载behaviac unitypackage 5. Unity中…

C#引用Microsoft.Office.Interop.Excel

1.添加相关包 在项目的引用上&#xff0c;鼠标右键点击&#xff0c;选择管理“NuGet程序包”&#xff0c;如下图所示。 2.搜索Microsoft.Office.Interop.Excel 打开后&#xff0c;按照下图所示进行操作。 3.查看引用 此时&#xff0c;在引用中&#xff0c;可以看见&#xff0c;…

K8s(Kubernetes)学习(五)——Service:ClusterIP、NodePort、LoadBalancer、 ExternalName

第五章 Service 什么是 Service为什么需要 ServiceService 特性Service 与 Pod 关联Service type 类型如何使用 Service多端口配置 1 什么是 Service 1.1 定义 官网地址: https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/ 将运行在一个或一组 Pod…

怎么推广自己抖店的商品?最适合0经验新手操作的办法,来看看

我是王路飞。 抖店开通后&#xff0c;想要把自己店铺的商品卖出去&#xff0c;就需要进行推广了。 但是怎么推广呢&#xff1f; 要么利用抖音的搜索和推荐流量&#xff0c;获取曝光&#xff0c;实现点击和转化。 不过这种玩法有个弊端&#xff0c;就是需要你有一定的电商经…

分布式事务-介绍

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…

K8S:pod资源限制及探针

文章目录 一.pod资源限制1.pod资源限制方式2.pod资源限制指定时指定的参数&#xff08;1&#xff09;request 资源&#xff08;2&#xff09; limit 资源&#xff08;3&#xff09;两种资源匹配方式 3.资源限制的示例&#xff08;1&#xff09;官网示例&#xff08;2&#xff0…

QSlider风格设置

QT的滑动条在开发的过程中经常使用&#xff0c;默认的QSlider风格比较简陋&#xff0c;一般达不到UI设计的效果&#xff0c;本篇记录一个QSlider使用过程中风格的设置。 1.qss常用的字段属性 1.1背景属性 属性值意思background Background背景属性background-colorBrush背景…

【探索C++】string类详解

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

pytest一些常见的插件

Pytest拥有丰富的插件架构&#xff0c;超过800个以上的外部插件和活跃的社区&#xff0c;在PyPI项目中以“ pytest- *”为标识。 本篇将列举github标星超过两百的一些插件进行实战演示。 插件库地址&#xff1a;http://plugincompat.herokuapp.com/ 1、pytest-html&#xff1…

浏览器缓存学习笔记

浏览器存储 示例&#xff1a;网页的搜索历史 application->Local Storage&#xff0c;数据通过key-value保存 保存数据 <button onclick"saveData()">点击保存数据</button><script type"text/javascript">let p { name: Jack, ag…

智慧食堂操作教程,建议收藏!

医院食堂作为医疗机构不可或缺的一部分&#xff0c;不仅要提供高质量、健康的餐饮选择&#xff0c;还需要为患者和医护人员提供便捷的用餐体验。 随着科技的不断发展&#xff0c;智慧收银系统应运而生&#xff0c;它已经在医疗机构中引起了广泛关注。智慧收银系统不仅为患者和医…

linux 设置打开文件数

可以使用下面的文件进行设置 /etc/security/limits.d/90-nproc.conf 先来看/etc/security/limits.d/90-nproc.conf 配置文件&#xff1a; [root ~]# cat /etc/security/limits.d/90-nproc.conf # Default limit for number of users processes to prevent # accidental fork…