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

ThreadLocal使用详解-从源码层面分析

从demo入手看效果

代码Demo

    static ThreadLocal tl1 = new ThreadLocal();static ThreadLocal tl2 = new ThreadLocal();static ThreadLocal tl3 = new ThreadLocal();public static void main(String[] args) {tl1.set("123");tl2.set("456");tl3.set("4586");Thread t1 = new Thread(() -> {System.out.println("t1:tl1-before:" + tl1.get());System.out.println("t1:tl2-before:" + tl2.get());System.out.println("t1:tl3-before:" + tl3.get());ThreadLocal tl4 = new ThreadLocal();tl1.set("1231");tl2.set("4561");tl3.set("12312");tl4.set("123121231212312");System.out.println("t1:tl1-" + tl1.get());System.out.println("t1:tl2-" + tl2.get());System.out.println("t1:tl3-" + tl3.get());System.out.println("t1:tl4-" + tl4.get());});t1.start();Thread.sleep(5000);System.out.println("main:tl1-" + tl1.get());System.out.println("main:tl2-" + tl2.get());System.out.println("main:tl3-" + tl3.get());

执行结果:

t1:tl1-before:null
t1:tl2-before:null
t1:tl3-before:null
t1:tl1-1231
t1:tl2-4561
t1:tl3-12312
t1:tl4-123121231212312
main:tl1-123
main:tl2-456
main:tl3-4586

结论:
根据结果可以发现 相同的ThreadLocal 在main线程和t1 线程存入不同的数据,拿到的结果不一样,即使主线程先在ThreadLocal执行set方法,在t1线程中还是获取为空,可以说明在T1线程内部获取ThreadLocal是获取不到main线程的,因此可以证明实现了线程隔离。

源码分析

Thread:

 ThreadLocal.ThreadLocalMap threadLocals = null;

ThreadLocal类中包含一个静态类 ThreadLocalMap,是一个定制化的哈希表,用于存储线程的私有数据。键为ThreadLocal对象(弱引用),值为线程的局部变量(强引用)
在这里插入图片描述
ThreadLocal的set方法源码:

设置该线程局部变量的当前线程副本到指定的值。大多数子类都不需要这样做重写此方法,仅依赖于{@link #initialValue}方法设置线程局部变量的值。public void set(T value) {Thread t = Thread.currentThread();//ThreadLocalMap map = getMap(t);if (map != null) {map.set(this, value);} else {createMap(t, value);}}

在上面set方法里先获取到执行该方法的线程对象,再基于此对象去获取该线程的ThreadLocalMap 来实现线程间的隔离数据
getMap

获取与ThreadLocal相关联的映射
ThreadLocalMap getMap(Thread t) {return t.threadLocals;}

createMap:创建该线程的ThreadLocalMap

void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);}

new ThreadLocalMap(this, firstValue)

ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {table = new Entry[INITIAL_CAPACITY];int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);table[i] = new Entry(firstKey, firstValue);size = 1;setThreshold(INITIAL_CAPACITY);}

**set方法执行结论:**先获取到执行该方法的线程对象,然后基于这个对象获取ThreadLocalMap,进行实例化,赋值。赋值的key就是ThreadLocal,虽然ThreadLocal在多线程中复用,但是实际存储数据的是ThreadLocalMap,这个ThreadLocalMap是和Thread绑定的

get方法

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();}

getMap

ThreadLocalMap getMap(Thread t) {return t.threadLocals;}

setInitialValue

private T setInitialValue() {T value = initialValue();Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {map.set(this, value);} else {createMap(t, value);}if (this instanceof TerminatingThreadLocal) {TerminatingThreadLocal.register((TerminatingThreadLocal<?>) this);}return value;}

get方法执行结论: 先拿到执行方法的当前线程 根据当前线程去获取map,有就以ThreadLocal为key去获取value。

http://www.lryc.cn/news/590841.html

相关文章:

  • Python 网络爬虫 —— requests 库和网页源代码
  • 智能体开发工具链全景图:IDE、调试器与监控平台
  • Fair-code介绍(Fair code)(一套新型软件模型:旨在“开源”“商业可持续性”中找到平衡)
  • Windows 11清理C盘方法大全:磁盘清理/禁用休眠/系统还原点/优化大师使用教程
  • Android默认背光亮度配置说明
  • 纯前端html实现图片坐标与尺寸(XY坐标及宽高)获取
  • SegNet:一种用于图像分割的深度卷积编码器解码器架构
  • RocketMQ 高可用集群架构与一致性机制解析
  • 【3D目标检测】Livox Tele-15采集的.lvx数据转.bag再转.pcd
  • 鲍威尔去留风波的AI量化解析:基于多模态数据驱动的金融市场脉冲响应研究
  • 达梦数据守护集群搭建(1主1实时备库1同步备库1异步备库)
  • 时序数据库选型指南 —— 为什么选择 Apache IoTDB?
  • javaweb学习开发代码_HTML-CSS-JS
  • Java面试(基础篇) - 第二篇!
  • slot=“trigger“ 覆盖了组件内部的 ref=“trigger“【详细来龙去脉版 5min】
  • Web开发 01
  • Python的“__name__“属性
  • visual freebasic教程-菜单栏
  • 视频码率是什么?视频流分辨率 2688x1520_25fps采用 h264格式压缩,其码率为
  • 线上协同办公时代:以开源AI大模型等工具培养网感,拥抱职业变革
  • Vim多列打开不同文件操作指南
  • Dijkstra 算法求解多种操作
  • 【真·CPU训模型!】单颗i7家用本,4天0成本跑通中文小模型训练!Xiaothink-T6-mini-Preview 技术预览版开源发布!
  • 腾讯云服务上下载docker以及使用Rabbitmq的流程
  • 闭包的两种设计模式
  • 【Android】ViewBinding(视图绑定)
  • OpenCV中常用特征提取算法(SURF、ORB、SIFT和AKAZE)用法示例(C++和Python)
  • YOLOv3 技术深度解析:从理论到实践的完整指南
  • Linux的Ext系列文件系统
  • 深入理解进程等待:wait的简化与waitpid的灵活性