ScheduledThreadPoolExecutor
1. 构造方法
- 默认构造方法
public ScheduledThreadPoolExecutor(int corePoolSize) {
//调用父类构造实现创建
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());
}
- 图解
- 描述
- 由于ScheduleThreadPoolExecutor使用了父类ThreadPoolExecutor的构造方法,传参中的任务队列为当前内部类,且并无初始化大小及DelayWorkQueue的构造方法,所以DelayedWorkQueue为无界队列,即没有容量限制
- 由于非核心线程的创建的前提条件是核心线程数与任务队列满载,所以ScheduleThreadExecutor的构造函数中除去核心线程数及任务队列其他参数无效
2. 执行方法
2.1 schedule()方法
/**
* @param Runnable command 待执行任务
* @param long delay 延迟时间
* @param TimeUnit unit delay的时间单位
*/
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
if (command == null || unit == null){
throw new NullPointerException();
}
RunnableScheduledFuture<?> t = decorateTask(command,new ScheduledFutureTask<Void>(command, null,triggerTime(delay, unit)));
delayedExecute(t);
return t;
}
- 相关图解
-
描述
- 由于接口在设计过程中需要满足单一原则,即接口隔离,如果想同时拥有两个或者两个以上接口的能力,那么需要继承对应接口,从而完成接口(能力)的组合
-
ScheduledFutureTask 代码详解
private class ScheduledFutureTask<V> extends FutureTask<V> implements RunnableScheduledFuture<V> {
//序列号,依据任务放入顺序严格递增
private final long sequenceNumber;
//超时时间,绝对时间
private long time;
//周期,每个多长时间执行一次,即 下次任务执行时间 = 绝对时间 + 周期
private final long period;
RunnableScheduledFuture<V> outerTask = this;
//索引,任务的存放是以小顶堆(二叉树)的形式存储
int heapIndex
//基于纳秒创建一次性任务
ScheduledFutureTask(Runnable r, V result, long ns) {
this(r, result,ns,0);
}
//基于纳秒创建周期性任务
ScheduledFutureTask(Runnable r, V result, long ns, long period) {
super(r, result);
this.time = ns;
this.period = period;
this.sequenceNumber = sequencer.getAndIncrement();
}
//基于纳秒创建一次性任务
ScheduledFutureTask(Callable<V> callable, long ns) {
super(callable);
this.time = ns;
this.period = 0;
this.sequenceNumber = sequencer.getAndIncrement();
}
public long getDelay(TimeUnit unit) {
return unit.convert(time - now(), NANOSECONDS);
}
public int compareTo(Delayed other) {
if (other == this) // compare zero if same object
return 0;
if (other instanceof ScheduledFutureTask) {
ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
long diff = time - x.time;
if (diff < 0)
return -1;
else if (diff > 0)
return 1;
else if (sequenceNumber < x.sequenceNumber)
return -1;
else
return 1;
}
long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}
//是否为周期性任务判断
public boolean isPeriodic() {
return period != 0;
}
/**
* Sets the next time to run for a periodic task.
*/
private void setNextRunTime() {
long p = period;
if (p > 0)
time += p;
else
time = triggerTime(-p);
}
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled && removeOnCancel && heapIndex >= 0)
remove(this);
return cancelled;
}
/**
* Overrides FutureTask version so as to reset/requeue if periodic.
*/
public void run() {
boolean periodic = isPeriodic();
if (!canRunInCurrentRunState(periodic))
cancel(false);
else if (!periodic)
ScheduledFutureTask.super.run();
else if (ScheduledFutureTask.super.runAndReset()) {
setNextRunTime();
reExecutePeriodic(outerTask);
}
}
}