定时线程池
使用场景:
1. 分布式锁 - redis
2. springCloud - 服务注册与发现中心
ScheduledThreadPoolExecutor
它用来处理延时任务或定时任务。
它接收SchduledFutureTask类型的任务,是线程池调度任务的最小单位,有三种提交任务的方式:
- schedule
- scheduledAtFixedRate
- scheduledWithFixedDelay
它采用DelayQueue存储等待的任务
- DelayQueue内部封装了一个PriorityQueue,它会根据time的先后时间排序,若time相同则根据sequenceNumber排序;
- DelayQueue也是一个无界队列;
任务提交上来后,会将任务封装为一个ScheduledFutureTask
SchduledFutureTask接收的参数(成员变量): 1. private long time:任务开始的时间 2. private final long sequenceNumber;:任务的序号 3. private final long period:任务执行的时间间隔 工作线程的执行过程: 工作线程会从DelayQueue取已经到期的任务去执行; 执行结束后重新设置任务的到期时间,再次放回DelayQueue。 ScheduledThreadPoolExecutor会把待执行的任务放到工作队列DelayQueue中, DelayQueue封装了一个PriorityQueue,PriorityQueue会对队列中的ScheduledFutureTask进行排序,具体的排序算法实现如下: 1. 首先按照time排序,time小的排在前面,time大的排在后面; 2. 如果time相同,按照sequenceNumber排序,sequenceNumber小的排在前面,sequenceNumber大的排在后面,换句话说,如果两个task的执行时间相同, 优先执行先提交的task。 SchduledFutureTask之run方法实现 run方法是调度task的核心,task的执行实际上是run方法的执行:1 public void run() { 2 boolean periodic = isPeriodic(); 3 //如果当前线程池已经不支持执行任务,则取消 4 if (!canRunInCurrentRunState(periodic)) 5 cancel(false); 6 //如果不需要周期性执行,则直接执行run方法然后结束 7 else if (!periodic) 8 ScheduledFutureTask.super.run(); 9 //如果需要周期执行,则在执行完任务以后,设置下一次执行时间 10 else if (ScheduledFutureTask.super.runAndReset()) { 11 // 计算下次执行该任务的时间 12 setNextRunTime(); 13 //重复执行任务 14 reExecutePeriodic(outerTask); 15 } 16 }
1. 如果当前线程池运行状态不可以执行任务,取消该任务,然后直接返回,否则执行 步骤2;
2. 如果不是周期性任务,调用FutureTask中的run方法执行,会设置执行结果,然后 直接返回,否则执行步骤3;
3. 如果是周期性任务,调用FutureTask中的runAndReset方法执行,不会设置执行 结果,然后直接返回,否则执行步骤4和步骤5;
4. 计算下次执行该任务的具体时间;
5. 重复执行任务。
DelayedWorkQueue
ScheduledThreadPoolExecutor之所以要自己实现阻塞的工作队列,是因为 ScheduledThreadPoolExecutor要求的工作队列有些特殊。
ScheduledThreadPoolExecutor之所以要自己实现阻塞的工作队列,是因为 ScheduledThreadPoolExecutor要求的工作队列有些特殊。 DelayedWorkQueue是一个基于堆的数据结构,类似于DelayQueue和 PriorityQueue。在执行定时任务的时候,每个任务的执行时间都不同,所以 DelayedWorkQueue的工作就是按照执行时间的升序来排列,执行时间距离当前时间越近 的任务在队列的前面(注意:这里的顺序并不是绝对的,堆中的排序只保证了子节点的下次 执行时间要比父节点的下次执行时间要大,而叶子节点之间并不一定是顺序的)。
heap -》堆结构
1. 最小根堆
2. 最大根堆
存储数据结构是一个数组。
End!
标签:run,任务,线程,time,DelayQueue,定时,执行 From: https://www.cnblogs.com/zhf123/p/16882626.html