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

线程池上下文参数传递

线程池中的核心线程在执行完任务后不会被销毁,而是回到池中等待下一个任务。当新任务到来时,线程池会分配一个空闲线程来执行。如果这个线程之前执行过某个任务,并且该任务设置了ThreadLocal变量,那么这些变量可能仍然存在于该线程中,导致后续任务访问到旧的数据,或者如果任务没有正确清理ThreadLocal变量,可能导致内存泄漏或数据混乱。

线程池中的线程被重复使用,而不是每次任务都创建新线程。这提高了效率,但也导致线程的ThreadLocal状态在任务之间持续存在。

ThreadLocal变量的生命周期与线程绑定。如果线程被复用,之前设置的变量仍然存在,除非显式清除。

传统做法是在任务执行前设置ThreadLocal变量,但线程池中的任务可能由不同的线程执行,导致主线程设置的ThreadLocal变量在任务线程中不可见。主线程设置ThreadLocal变量后,提交任务到线程池。任务可能在另一个线程执行,该线程的ThreadLocal变量未被设置,导致任务无法获取到主线程的上下文。或者,如果任务执行时设置了ThreadLocal变量,但执行完毕后未清除,后续使用同一线程的任务会看到旧数据。

如果使用ThreadLocal后没有调用remove()方法,线程池中的线程可能长时间存活,导致ThreadLocal关联的对象无法被回收,从而引发内存泄漏。

传统ThreadLocal在线程池中上下文丢失的原因主要是线程复用导致的状态残留和缺乏正确的上下文传递机制。而TTL通过捕获和恢复上下文快照解决了这个问题。

TtlRunnableTtlCallable 是阿里 transmittable-thread-local 工具库的核心类,用于在线程池中实现线程间参数传递。它们通过包装原始任务,在任务提交和执行过程中,自动完成上下文的 捕获、传递、恢复和清理。以下是它们的具体实现逻辑和关键动作:


1. 任务提交时:捕获当前线程的上下文

  • 动作
    当使用 TtlRunnable.get(task)TtlCallable.get(task) 包装任务时,会立即捕获当前线程中所有 TransmittableThreadLocal 变量的值,生成一个 上下文快照

  • 实现方式
    通过调用 TransmittableThreadLocal.Transmitter.capture() 方法,收集当前线程中所有注册的 TransmittableThreadLocal 实例及其值,存储为一个 Map<TransmittableThreadLocal<?>, Object> 结构。

  • 关键点
    仅捕获 TransmittableThreadLocal 的上下文,普通的 ThreadLoc


http://www.kler.cn/a/532549.html

相关文章:

  • 在Mac mini M4上部署DeepSeek R1本地大模型
  • 登录认证(5):过滤器:Filter
  • 【HTML入门】Sublime Text 4与 Phpstorm
  • LabVIEW如何有效地进行数据采集?
  • STM32 对射式红外传感器配置
  • csapp笔记3.6节——控制(1)
  • 解密K-means:简单易懂的算法指南
  • vue3 store刷新失效场景解决方案
  • C++基础系列【2】C++基本语法
  • leetcode——对称二叉树(java)
  • RabbitMQ深度探索:SpringBoot 整合 RabbitMQ
  • WordPress自定义.js文件排序实现方法
  • 【大模型理论篇】DeepSeek-R1:引入冷启动的强化学习
  • VSCode中代码颜色异常
  • 索引的底层数据结构、B+树的结构、为什么InnoDB使用B+树而不是B树呢
  • 使用 Postman 进行 API 测试:从入门到精通
  • 【漫话机器学习系列】079.超参数调优(Hyperparameter Tuning)
  • 了解 ALV 中的 field catalog (ABAP List Viewer)
  • 大数据治理:技术视角的解析
  • java项目当中的全局异常处理
  • WPS计算机二级•幻灯片的音视频表格与图形
  • 算法设计-哈夫曼树(C++)
  • kafka集群性能调优方案
  • DeepSeek 登顶140国应用商店榜首
  • 【BUUCTF杂项题】FLAG
  • C++输入输出(上)