踩坑系列之scheduleWithFixedDelay 和 scheduleAtFixedRate

简介:

定时任务和延时任务的理解

  • ScheduledExecutorService#scheduleAtFixedRate() 指的是“以固定的频率”执行,period(周期)指的是两次成功执行之间的时间。上一个任务开始的时间计时,一个period后,检测上一个任务是否执行完毕,如果上一个任务执行完毕,则当前任务立即执行,如果上一个任务没有执行完毕,则需要等上一个任务执行完毕后立即执行。
  • ScheduledExecutorService#scheduleWithFixedDelay() 指的是“以固定的延时”执行,delay(延时)指的是一次执行终止和下一次执行开始之间的延迟。

示例

scheduleAtFixedRate

public static void main(String[] args) {
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(
            "my-test-pool-%d").build();
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1, threadFactory);
        Date startTime = new Date();
        System.out.println("startTime: " + startTime.toString());
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            System.out.println("beginTime: " + new Date().toString());
            try {
                Thread.sleep(5 * 1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("endTime: " + new Date().toString());
        }, 2, 3, TimeUnit.SECONDS);
    }

输出:

startTime: Sun Feb 16 11:17:09 CST 2020
beginTime: Sun Feb 16 11:17:11 CST 2020
endTime: Sun Feb 16 11:17:16 CST 2020
beginTime: Sun Feb 16 11:17:16 CST 2020
endTime: Sun Feb 16 11:17:21 CST 2020
beginTime: Sun Feb 16 11:17:21 CST 2020
endTime: Sun Feb 16 11:17:26 CST 2020
beginTime: Sun Feb 16 11:17:26 CST 2020
endTime: Sun Feb 16 11:17:31 CST 2020
beginTime: Sun Feb 16 11:17:31 CST 2020
endTime: Sun Feb 16 11:17:36 CST 2020
beginTime: Sun Feb 16 11:17:36 CST 2020

当前任务执行时间大于等于间隔时间,任务执行后立即执行下一次任务。相当于连续执行了。

scheduleWithFixedDelay

public static void main(String[] args) {
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(
            "my-test-pool-%d").build();
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1, threadFactory);
        Date startTime = new Date();
        System.out.println("startTime: " + startTime.toString());
        scheduledExecutorService.scheduleWithFixedDelay(() -> {
            System.out.println("beginTime: " + new Date().toString());
            try {
                Thread.sleep(5 * 1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("endTime: " + new Date().toString());
        }, 2, 3, TimeUnit.SECONDS);
    }

输出:

startTime: Sun Feb 16 11:27:26 CST 2020
beginTime: Sun Feb 16 11:27:28 CST 2020
endTime: Sun Feb 16 11:27:33 CST 2020
beginTime: Sun Feb 16 11:27:36 CST 2020
endTime: Sun Feb 16 11:27:41 CST 2020
beginTime: Sun Feb 16 11:27:44 CST 2020
endTime: Sun Feb 16 11:27:49 CST 2020
beginTime: Sun Feb 16 11:27:52 CST 2020

每当上次任务执行完毕后,间隔一段时间执行。不管当前任务执行时间大于、等于还是小于间隔时间,执行效果都是一样的。

常见的“坑”

关于定时线程池(定时任务scheduleAtFixedRate和延时任务scheduleWithFixedDelay),好多人认为设置好频率(比如1Min),它会按照这个间隔按部就班的工作。但是,如果其中一次调度任务卡住的话,不仅这次调度失败,而且整个线程池也会停在这次调度上。

示例

如果run方法中抛出异常,而又没有捕获,会导致整个定时任务卡住。建议在整个run方法中使用try...catch...fianlly...处理。

public static void main(String[] args) {
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(
            "my-test-pool-%d").build();
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1, threadFactory);
        Date startTime = new Date();
        System.out.println("startTime: " + startTime.toString());
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            System.out.println("beginTime: " + new Date().toString());
            try {
                Thread.sleep(5 * 1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("endTime: " + new Date().toString());
            throw new NullPointerException();
        }, 2, 3, TimeUnit.SECONDS);
    }

image

目录
相关文章
|
5月前
|
调度 Apache
airflow scheduler -D 是什么作用
【6月更文挑战第30天】airflow scheduler -D 是什么作用
103 1
|
6月前
|
资源调度 Java
在SchedulerX中,你可以使用`schedulerx.submitTask(taskName)`方法来提交并执行单个任务
【1月更文挑战第7天】【1月更文挑战第34篇】在SchedulerX中,你可以使用`schedulerx.submitTask(taskName)`方法来提交并执行单个任务
63 1
|
2月前
Scheduler 【ChatGPT】
Scheduler 【ChatGPT】
|
3月前
|
Kubernetes API 调度
在k8S中,Scheduler作用及实现原理是什么?
在k8S中,Scheduler作用及实现原理是什么?
|
4月前
|
缓存 Java 调度
使用scheduleAtFixedRate进行定时任务调度
使用scheduleAtFixedRate进行定时任务调度
|
5月前
|
Kubernetes 监控 调度
K8S中Scheduler原理分析
【6月更文挑战第20天】K8S Scheduler是集群的关键组件,它监听API Server,为新Pod选择合适的Node。
|
6月前
|
调度
APScheduler任务相关操作
APScheduler任务相关操作
47 0
|
6月前
|
存储 NoSQL Java
APScheduler简介
APScheduler简介
72 0
|
6月前
|
资源调度
在SchedulerX中,你可以使用`schedulerx.output()`函数来向Worker报告运行结果
【1月更文挑战第7天】【1月更文挑战第35篇】在SchedulerX中,你可以使用`schedulerx.output()`函数来向Worker报告运行结果
45 1
|
6月前
|
资源调度 分布式计算 算法
Gang Scheduling
Gang Scheduling(Coscheduling)、FIFO Scheduling、Capacity Scheduling、Fair sharing、Binpack/Spread等是云计算和分布式系统中的任务调度算法,用于在资源有限的情况下,公平、高效地分配任务和资源。下面是这些调度算法的基本介绍和如何在实际应用中使用它们的一些建议:
290 2