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

【并发编程】ThreadLocal

从名字我们就可以看到 ThreadLocal 叫做线程变量,意思是 ThreadLocal 中填充的变量属于当前线程,该变量对其他线程而言是隔离的

ThreadLocal 为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。

static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(){ 
​@Override 
​protected Integer initialValue() { 
​return 1; 
​} 
​
};

ThreadLocal 原理分析

首先ThreadLocal是一个泛型类 ,保证可以接受任何类型的对象 。ThreadLocal内部维护了一个Map , ThreadLocal 实现了一个叫做ThreadLoalMap的静态内部类。ThreadLocalMap 类实现了对应的 get()、set() 方法。

set 方法

public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);}

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

最终的变量是放在了当前线程的ThreadLocalMap中 ,并不是存在 ThreadLocal 上,ThreadLocal 作为 key。

ThreadLocal 内存泄漏问题

TreadLocalMap 使用 ThreadLocal 的弱引用作为 key,如果一个 ThreadLocal不存在外部强引用时,Key(ThreadLocal)势必会被 GC 回收,这样就会导致ThreadLocalMap 中 key 为 null, 而 value 还存在着强引用,只有 thead 线程退出以后,value 的强引用链条才会断掉。

但如果当前线程再迟迟不结束的话,这些 key 为 null 的 Entry 的 value 就会一直存在一条强引用链:

Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value

永远无法回收,造成内存泄漏

ThreadLocal 正确的使用方法

每次使用完 ThreadLocal 都调用它的 remove()方法清除数据。

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

相关文章:

  • 如何提高自己的软件测试水平之bug定位
  • 发点实用的快捷键(mac
  • Android播放多媒体文件——播放音频
  • 存储重启后,ceph挂载信息没了,手动定位osd序号并挂载到对应磁盘操作流程、ceph查看不到osd信息处理方法
  • Linux学习之循环处理位置参数
  • NLP实战8:图解 Transformer笔记
  • Pytorch个人学习记录总结 玩俄罗斯方块の深度学习小项目
  • PuTTY连接服务器报错Connection refused
  • 11-3_Qt 5.9 C++开发指南_QSqlQuery的使用(QSqlQuery 是能执行任意 SQL 语句的类)
  • 神码ai火车头伪原创插件怎么用【php源码】
  • 13.Netty源码之Netty中的类与API
  • C# 如何检查数组列表中是否存在数组
  • AI课堂教学质量评估系统算法 yolov7
  • eventBus使用遇到的坑
  • ChatGPT应用|科大讯飞星火杯认知大模型场景创新赛开始报名了!
  • DM8 DSC备份还原
  • 【Docker--harbor私有仓库部署与管理】
  • 基于量子同态加密的安全多方凸包协议
  • MySQL案例——多表查询以及嵌套查询
  • AI 视频清晰化CodeFormer-Deepfacelab
  • TCP协议如何实现可靠传输
  • 万恶的Eclipse的使用
  • 文件上传--题目
  • 小程序创建
  • stable diffusion如何确保每张图的面部一致?
  • 保存Windows锁屏壁纸
  • 面向对象编程:深入理解内部类与抽象类的使用
  • linux安装oracle
  • 切面 基于Aspect注解自动切面, 省下注解判断逻辑 handler
  • golang,gin框架的请求参数(一)--推荐