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

【并发编程】聊聊定时任务ScheduledThreadPool的实现原理和源码解析

ScheduledThreadPoolExecutor 是在线程池的基础上 拓展的定时功能的线程池,主要有四种方式,具体可以看代码,
这里主要描述下

  • scheduleAtFixedRate : 除了第一次执行的时间,后面任务执行的时间 为 time = MAX(任务执行时间,每次等待时间) 取最大值
  • scheduleWithFixedDelay:除了第一次执行的时间,后面任务的时间为 任务执行时间+每次等待时间。
    在这里插入图片描述

使用案例

		// 创建一个定时任务线程池ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);// 延迟1S后执行executor.schedule(() -> {}, 1000, TimeUnit.MILLISECONDS);// 立马执行executor.execute(() -> {System.out.println("execute");});// 第一次延迟1S,之后每3S执行一次,如果任务时间超过3S,那么等任务执行后执行下一次任务executor.scheduleAtFixedRate(() -> {try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("at"+new Date());}, 1000, 3000, TimeUnit.MILLISECONDS);// 第一次延迟1S执行。任务执行完成后+3S 执行下一次任务executor.scheduleWithFixedDelay(() -> {try {TimeUnit.SECONDS.sleep(5);System.out.println("with"+new Date());} catch (InterruptedException e) {throw new RuntimeException(e);}},1000, 3000, TimeUnit.MILLISECONDS);

源码解析

其实主要就是把握ScheduledFutureTask 和 线程池的核心流程的类就可以。

ScheduledFutureTask

在这里插入图片描述
在这里插入图片描述

DelayedWorkQueue

本质是一个二叉树形式的堆结构,会将邻近执行时间的任务排在前面。

schedule 方法分析

整体的流程其实就是 封装定时任务,然后触发延迟执行。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

delayedExecute

在这里插入图片描述
在这里插入图片描述

ScheduledFutureTask.run方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

流程图

这里来简单描述下整体的流程
1.先将任务封装成一个任务 ScheduledFutureTask, 根据线程池状态判断是否执行或者删除任务
2.将任务添加到延迟队列中
3.根据线程池配置 看是否创建线程执行任务。
4.运行的线程不断从延迟队列中获取任务执行。

其实本质就是利用线程池复用机制 + 延迟队列 实现定时任务。

在这里插入图片描述

总结

ScheduledThreadPoolExecutor和ThreadPoolExecutor的区别:

  • ThreadPoolExecutor每次addwoker就会将自己的Task传进新创建的woker中的线程执行,因此woker会第一时间执行当前Task,只有线程数超过了核心线程才会将任务放进队列里
  • ScheduledThreadPoolExecutor是直接入队列,并且创建woker时传到woker的是null,说明woker中的线程刚启动时并没有任务执行,只能通过getTask去队列里取任务,取任务时会判断是否到了执行时间,因此具有了延时执行的特性,并且task执行完了,会将当前任务重新放进堆里,并设置下次执行的时间。
http://www.lryc.cn/news/548040.html

相关文章:

  • 【虚拟化】Docker Desktop 架构简介
  • DeepSeek 医疗大模型微调实战讨论版(第一部分)
  • c++实现最大公因数和最小公倍数
  • 知识库Dify和cherry无法解析影印pdf word解决方案
  • 【记录一下学习】Embedding 与向量数据库
  • 【第21节】C++设计模式(行为模式)-Chain of Responsibility(责任链)模式
  • createrepo centos通过nginx搭建本地源
  • 在 Docker 中搭建GBase 8s主备集群环境
  • 【MySQL-数据类型】数据类型分类+数值类型+文本、二进制类型+String类型
  • 小谈java内存马
  • 简单的二元语言模型bigram实现
  • 【清华大学】实用DeepSeek赋能家庭教育 56页PDF文档完整版
  • 黑洞如何阻止光子逃逸
  • 1.4 单元测试与热部署
  • window系统中的start命令详解
  • AI编程工具节选
  • 正则表达式,idea,插件anyrule
  • 原生iOS集成react-native (react-native 0.65+)
  • java错题总结
  • 【商城实战(10)】解锁商品信息录入与展示的技术密码
  • 2025年主流原型工具测评:墨刀、Axure、Figma、Sketch
  • MDM 如何彻底改变医疗设备的远程管理
  • OpenCV计算摄影学(18)平滑图像中的纹理区域同时保留边缘信息函数textureFlattening()
  • 用DeepSeek学Android开发:Android初学者遇到的常见问题有哪些?如何解决?
  • springboot 集成 MongoDB 基础篇
  • 大白话html语义化标签优势与应用场景
  • 恶劣天候三维目标检测论文列表整理
  • conda的环境起的jupyter用不了已经安装的包如何解决
  • 蓝桥杯题型
  • STM32-I2C通信协议