揭秘ScheduledThreadPoolExecutor 中ScheduleAtFixedRate迷惑行为

  1. ScheduledThreadPoolExecutor 中ScheduleAtFixedRate参数说明:
scheduleAtFixedRate(Runnable command,long initialDelay,long period, TimeUnit unit)

第一个command参数是任务实例,
第二个initialDelay参数是初始化延迟时间,
第三个period参数是间隔时间,
第四个unit参数是时间单元。

  1. ScheduledThreadPoolExecutor 中ScheduleAtFixedRate的表现行为主要有三中场景: 一个是command的任务完成时间一直小于period;一个是command的任务完成时间一直大于period;还有一种是command的任务完成时间有时大于period, 有时小于period。对这三种场景,我们分别举例讨论;

2.1 command的任务完成时间一直小于period
这种场景的很容易理解,command的开始时间,就是设定的固定周期;比如代码中period为3s,任务完成时间为1s,command每次开始的时间都是3s的周期;

public class SchedulerTest {
    private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
    static long deltaTime = 1000;
    @Test
    public void testFixedRate() throws InterruptedException {
        executor.scheduleAtFixedRate(new myRun(), 2, 3, TimeUnit.SECONDS);
        Thread.sleep(100000);
    }

    static class myRun implements Runnable{
        @Override
        public void run() {
            System.out.println("----测试开始--------"+ new Date().toLocaleString());
            try {
                Thread.sleep(deltaTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
----测试开始--------2021-8-25 14:58:52
----测试开始--------2021-8-25 14:58:55
----测试开始--------2021-8-25 14:58:58

2.2 command的任务完成时间一直大于period,则在command任务完成后,立即开始下次任务的执行;代码中command设定4s完成,period为3s,每次任务完成后,下次任务立即开始。

public class SchedulerTest {
    private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
    static long deltaTime = 4000;
    @Test
    public void testFixedRate() throws InterruptedException {
        executor.scheduleAtFixedRate(new myRun(), 2, 3, TimeUnit.SECONDS);
        Thread.sleep(100000);
    }

    static class myRun implements Runnable{
        @Override
        public void run() {
            System.out.println("----测试开始--------"+ new Date().toLocaleString());
            try {
                Thread.sleep(deltaTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("----测试结束--------"+new Date().toLocaleString());
        }
    }
}
----测试开始--------2021-8-25 15:07:50
----测试结束--------2021-8-25 15:07:54
----测试开始--------2021-8-25 15:07:54
----测试结束--------2021-8-25 15:07:58
----测试开始--------2021-8-25 15:07:58

2.3 command的任务完成时间有时大于period,有时小于period;
如下代码中设定的,period设定为3s,刚开始时,command任务的执行时间是6s,每执行一次减小1s,直到command的执行时间是1s;开始一段时间command的执行时间大于period,任务结束后,立马开始下次任务;当command的执行时间小于period时,仍有一段时间,在任务结束后,立即开始下一次的任务,直到任务的执行次数达到预定的频率,才再次按照period设定的周期开始运行。

public class SchedulerTest {
    private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
    static long deltaTime = 6000;
    @Test
    public void testFixedRate() throws InterruptedException {
        executor.scheduleAtFixedRate(new myRun(), 2, 3, TimeUnit.SECONDS);
        Thread.sleep(1000000);
    }

    static class myRun implements Runnable{
        @Override
        public void run() {
            System.out.println("----测试开始--------"+ new Date().toLocaleString());
            try {
                Thread.sleep(deltaTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (deltaTime > 1000) {
                deltaTime -= 1000;
            }
            System.out.println("---测试结束--------"+new Date().toLocaleString());
        }
    }
}
----测试开始--------2021-8-25 15:13:53
----测试结束--------2021-8-25 15:13:58
----测试开始--------2021-8-25 15:13:58
----测试结束--------2021-8-25 15:14:02
----测试开始--------2021-8-25 15:14:02
----测试结束--------2021-8-25 15:14:05
----测试开始--------2021-8-25 15:14:05
----测试结束--------2021-8-25 15:14:07
----测试开始--------2021-8-25 15:14:07
----测试结束--------2021-8-25 15:14:08
----测试开始--------2021-8-25 15:14:08
----测试结束--------2021-8-25 15:14:09
----测试开始--------2021-8-25 15:14:11
----测试结束--------2021-8-25 15:14:12
----测试开始--------2021-8-25 15:14:14
----测试结束--------2021-8-25 15:14:15
----测试开始--------2021-8-25 15:14:17
----测试结束--------2021-8-25 15:14:18
----测试开始--------2021-8-25 15:14:20
----测试结束--------2021-8-25 15:14:21
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值