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

java ThreadLocal源码分析

写个demo测试下:

private static void testThreadLocal() {ThreadLocal<Integer> threadLocal = new ThreadLocal<>();new Thread(){@Overridepublic void run() {threadLocal.set(9527);System.out.println("curr thread: " + Thread.currentThread().getName() + ", set 9527");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("curr thread: " + Thread.currentThread().getName() + ", getValue: " + threadLocal.get());}}.start();new Thread(){@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}threadLocal.set(250);System.out.println("curr thread: " + Thread.currentThread().getName() + ", set 250");System.out.println("curr thread: " + Thread.currentThread().getName() + ", getValue: " + threadLocal.get());}}.start();}

打印:

可以看出,同一个ThreadLocal对象,在不同的线程中设置值和取值互不干扰。

研究下源码。

Thread线程对象里面维护了一个ThreadLocalMap对象,上面示例中设置的值都是存在对应线程的ThreadLocalMap对象中,ThreadLocalMap用于存储其对应线程的数据:

看下如何创建ThreadLocalMap:

可以看出,ThreadLocalMap中有个table数组,用于存储Entry(键:ThreadLocal对象,值为需要保存的对象)。 table数组初始长度只有16, 根据threadLocalHashCode & 15得到索引,该索引范围0 - 15。 

后续table数组容量不够了会扩容该数组:

再看下Entry类:

继承了弱引用,当ThreadLocal对象没有强引用时可以被GC回收。

ThreadLocal核心方法:

1、set, 将需要保存的值保存到当前线程的ThreadLocalMap对象中。上面分析过,是通过键值对的方式保存,key为该ThreadLocal对象,value为要保存的对象。

2、get, 从当前线程的ThreadLocalMap中取出该ThreadLocal存的对象。

3、remove, 当存储数据不再使用时,记得调用remove方法移除数据,防止内存泄漏:

ok. 总结,通过ThreadLocal存储数据是存到调用线程中,不同线程存储的数据是互相独立的。可用于实现线程局部变量。

http://www.xdnf.cn/news/14841.html

相关文章:

  • 基于Java+springboot 的车险理赔信息管理系统
  • centos7.9安装ffmpeg6.1和NASM、Yasm、x264、x265、fdk-aac、lame、opus解码器
  • CentOS-7的“ifupdown“与Debian的“ifupdown“对比 笔记250706
  • 【LeetCode 热题 100】240. 搜索二维矩阵 II——排除法
  • [netty5: WebSocketFrameEncoder WebSocketFrameDecoder]-源码解析
  • 《Spring AI实战:Java智能开发速成指南》
  • 设计模式---观察者模式(发布-订阅模式)
  • 【STM32】通用定时器PWM
  • Spring AI(12)——调用多模态模型识别和生成图像
  • 关于笔记本充电,使用氮化镓充电器
  • Omi录屏专家 Screen Recorder by Omi 屏幕录制Mac
  • 高效处理大体积Excel文件的Java技术方案解析
  • 云原生 Serverless 架构下的智能弹性伸缩与成本优化实践
  • SNAT DNAT实验
  • 探索实现C++ STL容器适配器:优先队列priority_queue
  • MySQL CDC与Kafka整合指南:构建实时数据管道的完整方案
  • 前端常见 HTTP 状态码
  • DPDK 网卡驱动
  • WPF学习笔记(25)MVVM框架与项目实例
  • Stlink v2调试器采用SWD模式连接stm32f103c8t6核心板的接线方式
  • AI小智项目全解析:软硬件架构与开发环境配置
  • 信号与槽的总结
  • Linux内核深度解析:IPv4策略路由的核心实现与fib_rules.c源码剖析
  • bean注入的过程中,Property of ‘java.util.ArrayList‘ type cannot be injected by ‘List‘
  • 从“电话催维修“到“手机看进度“——售后服务系统开发如何重构客户体验
  • 历史数据分析——中证医药
  • 《数据维度的视觉重构:打造交互式高维数据可视化的黄金法则》
  • 如何解决Spring Boot中@Valid对List校验失效问题
  • Python小工具之PDF合并
  • Linux应用基础