Java -- 线程池 ScheduledThreadPoolExecutor

1、执行过程

1、使用 ThreadPoolExecutor 线程池来提交、运行任务,并实现 ScheduledExecutorService 接口类,
该类继承于 ExecutorService,使用的队列是 DelayedWorkQueue,添加了几个定时方法
2、将任务封装成 ScheduledFutureTask 类型,添加到延迟队列中

2、ScheduledFutureTask

实现了 RunnableScheduledFuture 多个方法,如 isPeriodic()、getDelay(),并重新实现 run 运行任务逻辑,作了一层封装
public void run() {
    boolean periodic = isPeriodic();
    //1.SHUTDOWN 状态下,周期性任务会停止,只执行一次的任务会继续执行完毕
    if (!canRunInCurrentRunState(periodic))
        cancel(false);
    else if (!periodic)
        //2.直接执行任务
        ScheduledFutureTask.super.run();
        //3.直接执行任务,并重置
    else if (ScheduledFutureTask.super.runAndReset()) {
        //4.设置下次需要执行的时间
        setNextRunTime();
        //5.再次放入延迟队列,等待下次执行
        reExecutePeriodic(outerTask);
    }
}

void reExecutePeriodic(RunnableScheduledFuture<?> task) {
    if (canRunInCurrentRunState(true)) {
        //1.添加到延迟任务队列中
        super.getQueue().add(task);
    if (!canRunInCurrentRunState(true) && remove(task))
        task.cancel(false);
    else
        //2.判断是否需要添加线程
        ensurePrestart();
    }
}

3、下次执行的时间

//两种情况都是在上次任务执行完毕之后执行, 不同的是:
//一种: 参考的是固定的频率, 10:00:00, 10:00:05, 10:00:10, 如果上次任务执行时间在间隔内, 那么按照以上频率去周期执行; 如果超过间隔, 那么上次任务执行完毕, 下次任务会立即执行; 类似于火车班次, 无论路上堵车了, 班次还是会定点开

//一种: 参考的是上次任务结束的时间, 根据这个时间, 往后推周期时间去执行
private void setNextRunTime() {
    long p = period;
    if (p > 0)
        time += p;
    else
        time = triggerTime(-p);
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值