0
点赞
收藏
分享

微信扫一扫

Java 线程池体系 - ScheduledThreadPoolExecutor

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);
            }
        }
    }

未完待续----------

举报

相关推荐

0 条评论