定时任务线程池-scheduleAtFixedRate和scheduleWithFixedDelay

定时任务线程池-scheduleAtFixedRate和scheduleWithFixedDelay

  • 前言
  • 一、核心区别
  • 二、源码处看区别
    • [2.1 提交任务的源码区别](#2.1 提交任务的源码区别)
    • [2.2 任务执行后的区别](#2.2 任务执行后的区别)
      • [2.2.1 ScheduledFutureTask 的 run](#2.2.1 ScheduledFutureTask 的 run)
      • [2.2.2 setNextRunTime](#2.2.2 setNextRunTime)
  • 三、代码示例
    • [3.1 scheduleAtFixedRate 执行时间大于间隔](#3.1 scheduleAtFixedRate 执行时间大于间隔)

前言

本章节介绍定时任务线程池中 scheduleAtFixedRatescheduleWithFixedDelay 的区别


一、核心区别

  1. scheduleAtFixedRate 是固定的频率执行,如果任务执行时间过程超过了固定频率需要注意不会并行执行,而是上个任务结束后立即执行下个任务
  2. scheduleWithFixedDelay 是固定的延迟执行,上一个任务执行完成后多长时间再次执行

二、源码处看区别

2.1 提交任务的源码区别

2.2 任务执行后的区别

ScheduledFutureTask 是最终提交给线程池的任务类,肯定实现了 Runnable 或者 Callable,其实是 Runnable,所以任务执行的时候肯定会执行它的 run()

2.2.1 ScheduledFutureTask 的 run

java 复制代码
public void run() {
if (!canRunInCurrentRunState(this))
         cancel(false);
     else if (!isPeriodic())
         super.run();
     // super.runAndReset 这里面会执行你提交的任务
     // 注意这里是同步的, 也就是说 setNextRunTime 是在当前任务结束后才会执行, 因此同一个任务不会并行执行
     else if (super.runAndReset()) {
     		// 设置下次执行时间
         setNextRunTime();
         reExecutePeriodic(outerTask);
     }
 }

2.2.2 setNextRunTime

java 复制代码
private void setNextRunTime() {
     long p = period;
     // 如果 period > 0, 是上次开始执行时间+间隔
     if (p > 0)
         time += p;
     else
     	// 如果 period<0, 则是需要重新计算下次执行时间
      time = triggerTime(-p);
 }

三、代码示例

3.1 scheduleAtFixedRate 执行时间大于间隔

java 复制代码
@Test
public void test2() {
     ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
     AtomicInteger counter = new AtomicInteger(1);
     ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(() -> {
         int currentNumber = counter.getAndIncrement();
         // 这里日志要打印时间戳, 否则没有效果
         log.info("AtFixed - start - {}", currentNumber);
         ThreadUtil.sleep(5L, TimeUnit.SECONDS);
         log.info("AtFixed - end - {}", currentNumber);
     }, 0, 2, TimeUnit.SECONDS);

     ThreadUtil.waiting();
 }
相关推荐
yhole4 分钟前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
zjjsctcdl5 分钟前
SpringBoot3.3.0集成Knife4j4.5.0实战
java
彭于晏Yan6 分钟前
Spring Boot 集成邮件服务实现发送邮件功能
java·spring boot·后端
浮尘笔记7 分钟前
Java Snowy 框架生产环境安全部署全流程(服务器篇)
java·运维·服务器·开发语言·后端
宸津-代码粉碎机8 分钟前
Spring Boot 4.0虚拟线程实战续更预告:高阶技巧、监控排查与分布式场景落地指南
java·大数据·spring boot·分布式·后端·python
Rsun0455110 分钟前
6、Java 适配器模式从入门到实战
java·开发语言·适配器模式
MaCa .BaKa12 分钟前
52-考研备考服务平台系统-考研系统
java·spring boot·mysql·考研·tomcat·maven·mybatis
_深海凉_14 分钟前
LeetCode热题100-最长公共子序列
java·开发语言·前端
8Qi817 分钟前
Elasticsearch实战篇:索引库、文档与JavaRestClient操作指南
java·大数据·elasticsearch·搜索引擎·微服务·架构·springcloud
落羽的落羽17 分钟前
【Linux系统】深入线程:多线程的互斥与同步原理,封装实现两种生产者消费者模型
java·linux·运维·服务器·c++·人工智能·python