这是定时任务的线程池,用户通过

schedule,scheduleAtFixedRate,scheduleWithFixedDelay

把定时任务加入到堆队列中,工作线程取出队列头元素,当任务执行完成后,重新设置任务的执行时间,放回到队列中。

使用过程中,有几点需要注意:

1. scheduleAtFixedRate 和 scheduleWithFixedDelay 的任务执行时间不同

scheduleAtFixedRate 提交的任务,执行时间是 t, t+p, t+2p
scheduleWithFixedDelay 提交的任务,执行时间是前一次任务执行完成时间加上 period

2. 如果提交的定时任务执行过程中出现异常,并且没有捕获,导致异常被抛出,后续的定时任务不会再执行

3. 工作线程有 leader-follower 之分
假定工作线程没有 leader-follower 区分,则 2 个线程尝试获取堆顶的任务,发现该任务并没有到期,则挂起线程 t 时间,t 时间后,2 个线程被唤醒,再次尝试获取堆顶的任务,只有一个线程能获取到任务,另一个线程获取失败由被挂起,这样的挂起-唤醒-挂起,做了很多无用功。

采用 leader-follower 模式后,则 2 个线程尝试获取堆顶的任务,发现该任务并没有到期,则抢占 leader,leader 挂起线程 t 时间,其他线程一直挂起,leader 线程取到堆顶元素后,重置 leader 为 null ,并唤醒其他挂起的线程。

posted on 2020-06-30 16:59  偶尔发呆  阅读(762)  评论(0)    收藏  举报