ScheduledThreadPoolExecutor 中ScheduleAtFixedRate 和 ScheduleWithFixedDelay方法讲解

java 中ScheduledExecutorService接口是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。

大家好,又见面了,我是全栈君。

java 中ScheduledExecutorService接口是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。
其中的一个实现类是ScheduledThreadPoolExecutor,ScheduledThreadPoolExecutor的uml类图关系如下:

这里写图片描述

(1)>ScheduledThreadPoolExecutor实现ScheduledExecutorService接口,实现了一些定时任务处理的方法。

(2)>ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,可以通过线程池进行任务的管理和调度。

下面介绍ScheduledThreadPoolExecutor中实现ScheduledExecutorService接口最常用的调度的两个方法ScheduleAtFixedRate 和 ScheduleWithFixedDelay。

一、scheduleAtFixedRate方法
1:方法简介

scheduleAtFixedRate(Runnable command,
                                long initialDelay,
                                  long period,
                                  TimeUnit unit)

上面的四个参数进行讲解:
第一个command参数是任务实例,
第二个initialDelay参数是初始化延迟时间,
第三个period参数是间隔时间,
第四个unit参数是时间单元。

2:代码实例
(1):当任务实例commod执行的时间小于间隔时间period情况

public class TestExecutor { 
   

    private static  ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);

    public static void main(String[] args) {


    }

    /** * 进行scheduleAtFixedRate测试 */
    public static void testFixedRate(){
        executor.scheduleAtFixedRate(new myRun(), 5, 5, TimeUnit.SECONDS);
    }


    static class myRun implements Runnable{

        @Override
        public void run() {
            System.out.println("----测试开始--------"+ new Date().toLocaleString());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("---休眠3秒后, 处理结束--------"+new Date().toLocaleString());
        }
    }


}

运行结果:

----测试开始--------2017-10-11 11:38:38 #第一次执行 ---休眠3秒后, 处理结束--------2017-10-11 11:38:41 #第一次任务处理,花费3秒  #第二次执行时间是第一次时间 + period 即38 + 5 = 43;
----测试开始--------2017-10-11 11:38:43 ---休眠3秒后, 处理结束--------2017-10-11 11:38:46 ----测试开始--------2017-10-11 11:38:48 ---休眠3秒后, 处理结束--------2017-10-11 11:38:51 ----测试开始--------2017-10-11 11:38:53

(2):当任务实例commod执行的时间大于间隔时间period情况
修改 Thread.sleep(3000); 为 Thread.sleep(6000);,执行查看运行结果!

运行结果:

----测试开始--------2017-10-11 11:41:22 #第一次执行时间 ---休眠3秒后, 处理结束--------2017-10-11 11:41:28 # 任务处理6秒,即 22+6 = 28 #第二次执行时间 == 上一次处理结束时间,因为任务处理时间大于period间隔时间
----测试开始--------2017-10-11 11:41:28 ---休眠3秒后, 处理结束--------2017-10-11 11:41:34 ----测试开始--------2017-10-11 11:41:34

3:总结
ScheduleAtFixedRate 每次执行时间为上一次任务开始起向后推一个时间间隔。分为两种情况:
(1)若command执行的时间小于period若每次执行时间为 :initialDelay, initialDelay+period, initialDelay+2*period, …;

(2)若command执行的时间大于period,则command执行完,下一次任务将立即执行!下即下一次任务不会按照预期的时间间隔执行,每次执行时间为 :initialDelay, initialDelay+taskExecutorTIme, initialDelay+2*taskExecutorTIme, …;

taskExecutorTIme为任务执行的时间!

二、scheduleWithFixedDelay

1:方法简介

scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit

上面的四个参数进行讲解:
第一个command参数是任务实例,
第二个initialDelay参数是初始换延迟时间,
第三个delay参数是延迟间隔时间,
第四个unit参数是时间单元

2:代码实例

(1):当任务实例commod执行的时间小于延迟间隔时间delay情况

public class TestExecutor { 
   

    private static  ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);

    public static void main(String[] args) {
        testFixedDelay();

    }




    public static void testFixedDelay(){
        executor.scheduleWithFixedDelay(new myRun(), 5, 5, TimeUnit.SECONDS);
    }


    static class myRun implements Runnable{ 
   

        @Override
        public void run() {
            System.out.println("----测试开始--------"+ new Date().toLocaleString());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("---休眠3秒后, 处理结束--------"+new Date().toLocaleString());
        }
    }


}

运行结果:

----测试开始--------2017-10-11 11:59:02 #第一次执行时间 ---休眠3秒后, 处理结束--------2017-10-11 11:59:05 #任务处理的时间,3秒 #第二次执行的时间 == 第一次任务开始时间+任务处理时间+delay延迟时间
#即 10 == 02 + 3秒 +  5秒 
----测试开始--------2017-10-11 11:59:10 ---休眠3秒后, 处理结束--------2017-10-11 11:59:13 ----测试开始--------2017-10-11 11:59:18 ---休眠3秒后, 处理结束--------2017-10-11 11:59:21 ....

(2):当任务实例commod执行的时间大于延迟间隔时间delay情况
将Thread.sleep(3000); 修改为 Thread.sleep(6000);
运行结果:

----测试开始--------2017-10-11 12:02:48 #第一次任务执行开始时间 ---休眠6秒后, 处理结束--------2017-10-11 12:02:54 #任务处理的时间 ,6秒 #第二次任务执行开始时间 == 第一次任务执行开始时间 + 任务处理的时间 + delay延迟时间
#即 59 == 48 + 6 + 5 
----测试开始--------2017-10-11 12:02:59 ---休眠6秒后, 处理结束--------2017-10-11 12:03:05 ----测试开始--------2017-10-11 12:03:10 ......

3:总结
不管任务command执行的时间是多长,下一次任务的执行时间都是上一次任务执行完后在等待延迟间隔delay时间后执行下一次任务。
ScheduleWithFixedDelay 每次执行时间为上一次任务结束起向后推一个时间间隔,即每次执行时间为:initialDelay, initialDelay+executeTime+delay, initialDelay+2*executeTime+2*delay。

三、参考
https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/



如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!


欢迎访问我的csdn博客,我们一同成长!

不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

博客首页http://blog.csdn.net/u010648555

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/121135.html原文链接:https://javaforall.net

(0)
上一篇 2022年2月26日 下午7:00
下一篇 2022年2月26日 下午7:00


相关推荐

  • SkipList详解

    SkipList详解本文参考 大数据日知录 概念 SkipList 是一种用来代替平衡树的数据结构 虽然在最坏的情况下 SkipList 的效率要低于平衡树 但是大多数情况下效率仍然非常高 其插入 删除 查找的时间复杂度都是 O log N 除了高效外 其实现和维护非常简单也是一大优势 SkipList 的使用还是比较广泛的 比如在 LevelDB 中的 MemTable 就是使用 SkipList 实现的 Redis 的

    2026年3月26日
    2
  • oracle数据库运维服务

    oracle数据库运维服务oracle 数据库运维服务 360oracle 技术服务中心可提供以下运维服务数据库容灾服务数据灾备系统式保障数据安全的重要手段之一 OracleDataGu 通过使用称为 standbydatab 的数据库来防止出现数据的灾难 它通过将 prinarydatab 数据库的重做日志传到并应用到 standbydatab 数据库来使 standby

    2026年3月17日
    1
  • Windows下搭建Airtest自动化测试环境

    Windows下搭建Airtest自动化测试环境一 下载 python 1 去官网下载 https www python org 2 百度网盘分享 python 3 5 1 exe 链接 https pan baidu com s 127QEBpb5e7Y 提取码 82n7 下载好后 安装二 配置 python 环境变量配置 python 环境 1 右击我的电脑 属性 高级系统设置 环境变量 系统变量中的 path 添加安装 python 的根目录 2 右击我的电脑 属性

    2026年3月18日
    2
  • chinese zodiac signs_icpc铜奖

    chinese zodiac signs_icpc铜奖输入23 14 3输出Impossible2 1 4 33 4 1 24 3 2 1题解 找规律+构造#include<bits/stdc++.h>using namespace std;const int N = 1001;int ch[N][N];int lowbit(int x){ return x & (-x);}int main(){ int n,k; int T; cin>>T; ..

    2022年8月11日
    5
  • 爬山算法 ( Hill Climbing )/模拟退火(SA,Simulated Annealing)

    爬山算法 ( Hill Climbing )/模拟退火(SA,Simulated Annealing)一 爬山算法 HillClimbing 爬山算法是一种简单的贪心搜索算法 该算法每次从当前解的临近解空间中选择一个最优解作为当前解 直到达到一个局部最优解 爬山算法实现很简单 其主要缺点是会陷入局部最优解 而不一定能搜索到全局最优解 假设 C 点为当前解 爬山算法搜索到 A 点这个局部最优解就会停止搜索 因为在 A 点无论向那个方向小幅度移动都不能得到更优的解 nbsp 二 模拟退火 SA

    2026年3月17日
    3
  • OpenClaw 自己写 Skill 完整教程(2026):从零开始,10 分钟做出第一个技能包

    OpenClaw 自己写 Skill 完整教程(2026):从零开始,10 分钟做出第一个技能包

    2026年3月13日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号