深入分析ScheduledThreadPoolExecutor的源码

上篇文章我们讲解了Timer的实现机制,但是Timer定时器是单线程的,如果该线程终止的话,那么定时任务将无法执行,为此jdk1.5后推出了ScheduledThreadPoolExecutor,用于执行定时任务,为此我们在这里就分析一下ScheduledThreadPoolExecutor的具体实现么,因为ScheduledThreadPoolExecutor是基于ThreadPoolExecutor开发,所以请确保你有ThreadPoolExecutor的源码阅读经验,这里给大家推荐一篇大牛写的好文章https://www.cnblogs.com/trust-freedom/p/6594270.html,如果涉及到线程池我会带过,你看这篇上面那篇文章就知道了,另外你也需要知道FutureTask的底层机制,这个可以看我的另一篇博客https://blog.csdn.net/qq_32459653/article/details/81566639,这里面详细讲解了FutureTask的底层运行机制,有助于你理解ScheduledFutureTask是怎么工作的,应为它两为父子类关系。

package java.util.concurrent;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.*;


public class ScheduledThreadPoolExecutor
        extends ThreadPoolExecutor
        implements ScheduledExecutorService {

   

    /**
      *        在shutdown后是否应该继续周期性任务 ture代表继续
     */
    private volatile boolean continueExistingPeriodicTasksAfterShutdown;

    /**
     * 
     * 在shutdown后是否应该取消延迟任务 true代表取消
     */  
    private volatile boolean executeExistingDelayedTasksAfterShutdown = true;

    /**  ScheduledFutureTask状态为cancel是否应该移除,true代表是
     * True if ScheduledFutureTask.cancel should remove from queue
     */
    private volatile boolean removeOnCancel = false;

    /** 
     * sequencer号生成器,每个ScheduledFutureTask,依靠sequencer生成序列号
     * 如果不同的ScheduledFutureTask具有相同的执行时间,会优先执行序列号大的ScheduledFutureTask
     */
    private static final AtomicLong sequencer = new AtomicLong();

    /** 返回当前时间
     * Returns current nanosecond time.
     */
    final long now() {
        return System.nanoTime();
    }

 //一个定时任务类,继承自futureTask,也意味着我们可以回去到执行结果

    private class ScheduledFutureTask<V>
            extends FutureTask<V> implements RunnableScheduledFuture<V> {

        /*任务序列号 */
        private final long sequenceNumber;

        
        /** 任务可以被执行的时间 单位为 nanoTime units */
        private long time;

        /**
         *  重复执行任务的周期,正数代表使用fixed-rate,负数代表fixed-delay,0代表不是重复任务
         */
        private final long period;

        /**  对于周期性执行任务而言 指向“ 外层”的任务,初始指向自身(默认),

        *这里主要是由于decorateTask(由用户覆盖)可能会对本该任务“ 包装一番” 

       * outerTask会指向decorateTask的返回值,

       */
        RunnableScheduledFuture<V> outerTask = this; 

        /** delay queue的索引,作用是支持快速删除,
         * Index into delay queue, to support faster cancellation.
         */
        int heapIndex;

        /** 创建一个只指定触发时间只执行一次的ScheduledFutureTask任务,
         * Creates a one-shot action with given nanoTime-based trigger time.
         */
        ScheduledFutureTask(Runnable r, V result, long ns) {
            super(r, result);
            this.time = ns;
            this.period = 0;
            this.sequenceNumber = sequencer.getAndIncrement();
        }

        /** 创建一个给定指定延迟时间周期性执行的ScheduledFutureTask
         * Creates a periodic action with given nano time and period.
         */
        ScheduledFutureTask(Runnable r, V result, long ns, long period) {
            super(r, result);
            this.time = ns;
            this.period = period;
            this.sequenceNumber = sequencer.getAndIncrement();
        }

        /**
         * 与上面类似,只不过过使用callable带返回结果
         */
        ScheduledFutureTask(Callable<V> callable, long ns) {
            super(callable);
            this.time = ns;
            this.period = 0;
            this.sequenceNumber = sequencer.getAndIncrement();
        }

           //获取任务剩余的延迟时间,也就是还差多少时间执行,单位为NANOSECONDS
        public long getDelay(TimeUnit unit) {
            return unit.convert(time - now(), NANOSECONDS);
        }
        //用于比较两个ScheduledFutureTask执行时间的先后的大小,在被添加到DelayedWorkQueue的队列中被排序时将会被用到
        public int compareTo(Delayed other) {
            if (other == this) // compare zero if same object
                return 0;
            if (other instanceof ScheduledFutureTask) { // 是ScheduledFutureTask,则比较执行的时间
                ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
                long diff = time - x.time;
                if (diff < 0) //小于返回-1
                    return -1;
                else if (diff > 0) 大于返回1
                    return 1;
                else if (sequenceNumber < x.sequenceNumber) //相等则比较sequenceNumber
                    return -1;
                else
                    return 1;
            }
            //other不是ScheduledFutureTask型,则直接比较下次距离下次执行时间的大小
            long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);
            return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
        }

        /**
         * 
         *判断是否是周期性执行的任务,为0代表周期性执行
         *
         */
        public boolean isPeriodic() { 
            return period != 0;
        }

        /**
         * 对于周期性执行的任务, 设置下次执行的时间

         * 参数p大于0,在使用scheduleWithiFixedDelay,会取period的负数而scheduleAtFixedRate则取正数以此来控制     

        * 是相对时间执行周期,还是绝对时间执行, 对此有疑问可以看关于Timer源码的详解,里面对此解读的比较清晰
         */
        private void setNextRunTime() { 
            long p = period;
            if (p > 0)  //p大于0说明是绝对时间,对应Timer里面的SchedlutAtFixedRate;
                time += p;
            else
                time = triggerTime(-p); //p小于0说明是相对执行执行 对应Timer定时器里面的schedule
        }

         //取消任务
        public boolean cancel(boolean mayInterruptIfRunning) {
            boolean cancelled = super.cancel(mayInterruptIfRunning);
            if (cancelled && removeOnCancel && heapIndex >= 0)
                remove(this);
            return cancelled;
        }

        /**
         * 覆盖FutureTask原有的run,方法,线程池中的线程取出ScheduledFutureTask,就是就是调用此方法的
         * 所以如果是周期性任务,会在此处重新加入任务队列
         */
        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); //将该任务加入到任务队列
            }
        }
    }

    /**
     * 
     * 判断当前是否可以运行
     *
     * @param periodic true if this task periodic, false if delayed
     */
    boolean canRunInCurrentRunState(boolean periodic) {//与文章首部设置的字段值有关,可参考值的含义
        return isRunningOrShutdown(periodic ?
                                   continueExistingPeriodicTasksAfterShutdown :
                                   executeExistingDelayedTasksAfterShutdown);
    }

    /**
     * 该方法主要是针对延迟或者周期性执行的任务 ,如果线程池是shut down,将拒绝该任务,否则将添加到任务队列中,并启       *  动一个线程,
     * @param task the task
     */
    private void delayedExecute(RunnableScheduledFuture<?> task) {
        if (isShutdown()) //关闭状态
            reject(task); //拒接任务
        else {
            super.getQueue().add(task); //将任务添加到任务队列当中,会由线程池中的线程取出进行执行
            if (isShutdown() &&
                !canRunInCurrentRunState(task.isPeriodic()) &&
                remove(task)) //如果线程池关闭,并且将canRunInCurrentRunStater返回false,remove成功,设置任务为取消状态
                task.cancel(false);//取消任务
            else
                ensurePrestart(); //确保被加入到任务队列的任务执行完成,可以参考线程池的实现,也就是确保有一个线程在运行
        }
    }

    /**
     * 将周期性执行任务重新入队,
     * 
     *
     * @param task the task
     */
    void reExecutePeriodic(RunnableScheduledFuture<?> task) {//
        if (canRunInCurrentRunState(true)) {//如果当前线程池还处于可运行的状态,重新调度的必是周期任务,所以参数为true
            super.getQueue().add(task); //加入的队列中
            if (!canRunInCurrentRunState(true) && remove(task)) //
                task.cancel(false);
            else
                ensurePrestart();
        }
    }

    /**
     *
     * 
     */
    @Override void onShutdown() { //取消并清楚任务队里中的任务,并关闭线程池
        BlockingQueue<Runnable> q = super.getQueue(); //获取任务队列
        boolean keepDelayed =
            getExecuteExistingDelayedTasksAfterShutdownPolicy(); 
        boolean keepPeriodic =
            getContinueExistingPeriodicTasksAfterShutdownPolicy();
        if (!keepDelayed && !keepPeriodic) { //两个变量都为假,
            for (Object e : q.toArray())
                if (e instanceof RunnableScheduledFuture<?>)
                    ((RunnableScheduledFuture<?>) e).cancel(false);
            q.clear();
        }
        else {//有一个为真,说明即使调用onShutdown后,也允许部分任务执行,具体请看文章头部,介绍的属性值控制
            // Traverse snapshot to avoid iterator exceptions
            for (Object e : q.toArray()) {
                if (e instanceof RunnableScheduledFuture) {
                    RunnableScheduledFuture<?> t =
                        (RunnableScheduledFuture<?>)e;
                    if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) || //如果t是周期性任务,则为 !keepPeriodic,否则为!keepDelayed ,
                        t.isCancelled()) { // also remove if already cancelled //在与t.isCancelled做或运算,以此来判断次任务是否应该被移除
                        if (q.remove(t))
                            t.cancel(false);
                    }
                }
            }
        }
        //尝试关闭线程池,请参考线程池源码解析
        tryTerminate();
    }

 
 
    protected <V> RunnableScheduledFuture<V> decorateTask( //没有任务作用,可由用户覆盖,添加下自己的执行逻辑
        Runnable runnable, RunnableScheduledFuture<V> task) {
        return task;
    }

   
   
    protected <V> RunnableScheduledFuture<V> decorateTask( //没有任务作用,可由用户覆盖,添加下自己的执行逻辑
        Callable<V> callable, RunnableScheduledFuture<V> task) {
        return task;
    }

   
    public ScheduledThreadPoolExecutor(int corePoolSize) { //初始化线程池
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

   //构造函数 
    public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue(), threadFactory);
    }

   //构造函数 

    public ScheduledThreadPoolExecutor(int corePoolSize,
                                       RejectedExecutionHandler handler) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue(), handler);
    }

      //构造函数 
    public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory,
                                       RejectedExecutionHandler handler) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue(), threadFactory, handler);
    
    /** //返回触发时间,具体看其重载的方法
     * Returns the trigger time of a delayed action.
     */
    private long triggerTime(long delay, TimeUnit unit) {
        return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));
    }

    /**
     *返回触发时间
     */
    long triggerTime(long delay) {
        return now() +
            ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
    }

   //说实话这个方法不太重要,主要是怕用户所设定的时间太长,而导致任务不能执行(比如几百年后)
   //这里的细节部分我也没有深究,一般用不到,
    private long overflowFree(long delay) {
        Delayed head = (Delayed) super.getQueue().peek();
        if (head != null) {
            long headDelay = head.getDelay(NANOSECONDS);
            if (headDelay < 0 && (delay - headDelay < 0))
                delay = Long.MAX_VALUE + headDelay;
        }
        return delay;
    }

    /**
     * 
     * //调用任务
     */
    public ScheduledFuture<?> schedule(Runnable command,
                                       long delay,
                                       TimeUnit unit) {
        if (command == null || unit == null) //为空?抛出异常
            throw new NullPointerException();

      //这里通过command构建一个RunnableScheduledFuture

      //decorateTask,由用户覆盖(子类),可以对原有任务进行修改(装饰)
        RunnableScheduledFuture<?> t = decorateTask(command, 
            new ScheduledFutureTask<Void>(command, null,
                                          triggerTime(delay, unit)));
        delayedExecute(t); //主要执行任务的函数,具体下面会分析
        return t;
    }

    /**
     * 
     * 与上面类型只不过上面是runnable
     */
    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
                                           long delay,
                                           TimeUnit unit) {
        if (callable == null || unit == null)
            throw new NullPointerException();
        RunnableScheduledFuture<V> t = decorateTask(callable,
            new ScheduledFutureTask<V>(callable,
                                       triggerTime(delay, unit)));
        delayedExecute(t); //
        return t;
    }

    //以绝对时间周期性调度某任务,类似于Timer定时器的schedulaAtFixedRate调度

   //其他方面都一样
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit) {
        if (command == null || unit == null)
            throw new NullPointerException();
        if (period <= 0) 
            throw new IllegalArgumentException();
        ScheduledFutureTask<Void> sft =
            new ScheduledFutureTask<Void>(command,
                                          null,
                                          triggerTime(initialDelay, unit),
                                          unit.toNanos(period));
        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
        sft.outerTask = t; //获取任务 sft的指向decorateTask返回值,由于默认什么都没做,这里指向自身
        delayedExecute(t);//调度任务
        return t;
    }

    /**
     * 周期性相对时间执行某任务,类似Timer定时器里面的Schedule,
     * @throws NullPointerException       {@inheritDoc}
     * @throws IllegalArgumentException   {@inheritDoc}
     *
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit) {
        if (command == null || unit == null)
            throw new NullPointerException();
        if (delay <= 0) //延后时间不能小于0,
            throw new IllegalArgumentException();
        ScheduledFutureTask<Void> sft =
            new ScheduledFutureTask<Void>(command,
                                          null,
                                          triggerTime(initialDelay, unit),
                                          unit.toNanos(-delay));
        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
        sft.outerTask = t;
        delayedExecute(t);
        return t;
    }

  
  
    public void execute(Runnable command) { //执行任务,
        schedule(command, 0, NANOSECONDS); //
    }

    // Override AbstractExecutorService methods

    /**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public Future<?> submit(Runnable task) {
        return schedule(task, 0, NANOSECONDS);
    }

    /**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public <T> Future<T> submit(Runnable task, T result) {
        return schedule(Executors.callable(task, result), 0, NANOSECONDS);
    }

    /**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public <T> Future<T> submit(Callable<T> task) {
        return schedule(task, 0, NANOSECONDS);
    }

    /**
     * Sets the policy on whether to continue executing existing
     * periodic tasks even when this executor has been {@code shutdown}.
     * In this case, these tasks will only terminate upon
     * {@code shutdownNow} or after setting the policy to
     * {@code false} when already shutdown.
     * This value is by default {@code false}.
     *
     * @param value if {@code true}, continue after shutdown, else don't
     * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy
     */
    public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
        continueExistingPeriodicTasksAfterShutdown = value;
        if (!value && isShutdown())
            onShutdown();
    }

    /**
     * Gets the policy on whether to continue executing existing
     * periodic tasks even when this executor has been {@code shutdown}.
     * In this case, these tasks will only terminate upon
     * {@code shutdownNow} or after setting the policy to
     * {@code false} when already shutdown.
     * This value is by default {@code false}.
     *
     * @return {@code true} if will continue after shutdown
     * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
     */
    public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
        return continueExistingPeriodicTasksAfterShutdown;
    }

 
    public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
        executeExistingDelayedTasksAfterShutdown = value;
        if (!value && isShutdown())
            onShutdown();
    }

    /**
     * @return {@code true} if will execute after shutdown
     * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
     */
    public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
        return executeExistingDelayedTasksAfterShutdown;
    }

    /**
     * Sets the policy on whether cancelled tasks should be immediately
     * removed from the work queue at time of cancellation.  This value is
     * by default {@code false}.
     *
     * @param value if {@code true}, remove on cancellation, else don't
     * @see #getRemoveOnCancelPolicy
     * @since 1.7
     */
    public void setRemoveOnCancelPolicy(boolean value) {
        removeOnCancel = value;
    }

    /**
     * Gets the policy on whether cancelled tasks should be immediately
     * removed from the work queue at time of cancellation.  This value is
     * by default {@code false}.
     *
     * @return {@code true} if cancelled tasks are immediately removed
     *         from the queue
     * @see #setRemoveOnCancelPolicy
     * @since 1.7
     */
    public boolean getRemoveOnCancelPolicy() {
        return removeOnCancel;
    }

 

    /**
     * @throws SecurityException {@inheritDoc}
     */
    public void shutdown() {
        super.shutdown();
    }

    /**
     * Attempts to stop all actively executing tasks, halts the
     * processing of waiting tasks, and returns a list of the tasks
     * that were awaiting execution.
     *
     * <p>This method does not wait for actively executing tasks to
     * terminate.  Use {@link #awaitTermination awaitTermination} to
     * do that.
     *
     * <p>There are no guarantees beyond best-effort attempts to stop
     * processing actively executing tasks.  This implementation
     * cancels tasks via {@link Thread#interrupt}, so any task that
     * fails to respond to interrupts may never terminate.
     *
     * @return list of tasks that never commenced execution.
     *         Each element of this list is a {@link ScheduledFuture},
     *         including those tasks submitted using {@code execute},
     *         which are for scheduling purposes used as the basis of a
     *         zero-delay {@code ScheduledFuture}.
     * @throws SecurityException {@inheritDoc}
     */
    public List<Runnable> shutdownNow() {
        return super.shutdownNow();
    }

    /**
     * Returns the task queue used by this executor.  Each element of
     * this queue is a {@link ScheduledFuture}, including those
     * tasks submitted using {@code execute} which are for scheduling
     * purposes used as the basis of a zero-delay
     * {@code ScheduledFuture}.  Iteration over this queue is
     * <em>not</em> guaranteed to traverse tasks in the order in
     * which they will execute.
     *
     * @return the task queue
     */
    public BlockingQueue<Runnable> getQueue() {
        return super.getQueue();
    }

    //延迟任务队里,DelayQueue的变种,不知道DelayQueue,可以看看我对DelayQueue源码的详解
    //其中该类里面涉及到了堆排序,这里对该算法就不做出详解了,一般程序员都会堆排序,不会的可要赶紧补!!
    static class DelayedWorkQueue extends AbstractQueue<Runnable>
        implements BlockingQueue<Runnable> {

          //初始容量大小
        private static final int INITIAL_CAPACITY = 16;
        
        private RunnableScheduledFuture<?>[] queue =
            new RunnableScheduledFuture<?>[INITIAL_CAPACITY];
        private final ReentrantLock lock = new ReentrantLock();
        private int size = 0;

       //表明在该队列上等待的线程,主要是为了降低线程间锁竞争,
       //一次,只有一个线程可以在该队列上取任务执行,
        private Thread leader = null;

        private final Condition available = lock.newCondition();

        /**
         * Sets f's heapIndex if it is a ScheduledFutureTask.
         */
        private void setIndex(RunnableScheduledFuture<?> f, int idx) {
            if (f instanceof ScheduledFutureTask)
                ((ScheduledFutureTask)f).heapIndex = idx;
        }

          //堆排序的变种 向上调整,堆排序涉及到的一部分,注意执行该操作前,请确保持有锁
         
        private void siftUp(int k, RunnableScheduledFuture<?> key) {
            while (k > 0) {
                int parent = (k - 1) >>> 1;
                RunnableScheduledFuture<?> e = queue[parent];
                if (key.compareTo(e) >= 0)
                    break;
                queue[k] = e;
                setIndex(e, k);
                k = parent;
            }
            queue[k] = key;
            setIndex(key, k);
        }

        /**
         * 向下调整,堆排序涉及到的一部分,注意执行该操作前,请确保持有锁
         * 
        private void siftDown(int k, RunnableScheduledFuture<?> key) {
            int half = size >>> 1;
            while (k < half) {
                int child = (k << 1) + 1;
                RunnableScheduledFuture<?> c = queue[child];
                int right = child + 1;
                if (right < size && c.compareTo(queue[right]) > 0)
                    c = queue[child = right];
                if (key.compareTo(c) <= 0)
                    break;
                queue[k] = c;
                setIndex(c, k);
                k = child;
            }
            queue[k] = key;
            setIndex(key, k);
        }

        /**
         * 扩容操作,
         */
        private void grow() {
            int oldCapacity = queue.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
            if (newCapacity < 0) // overflow
                newCapacity = Integer.MAX_VALUE;
            queue = Arrays.copyOf(queue, newCapacity);
        }

        /**
         * Finds index of given object, or -1 if absent.
         */
        private int indexOf(Object x) {
            if (x != null) {
                if (x instanceof ScheduledFutureTask) {
                    int i = ((ScheduledFutureTask) x).heapIndex;
                    // Sanity check; x could conceivably be a
                    // ScheduledFutureTask from some other pool.
                    if (i >= 0 && i < size && queue[i] == x)
                        return i;
                } else {
                    for (int i = 0; i < size; i++)
                        if (x.equals(queue[i]))
                            return i;
                }
            }
            return -1;
        }

        public boolean contains(Object x) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                return indexOf(x) != -1;
            } finally {
                lock.unlock();
            }
        }

        public boolean remove(Object x) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                int i = indexOf(x);
                if (i < 0)
                    return false;

                setIndex(queue[i], -1);
                int s = --size;
                RunnableScheduledFuture<?> replacement = queue[s];
                queue[s] = null;
                if (s != i) {
                    siftDown(i, replacement);
                    if (queue[i] == replacement)
                        siftUp(i, replacement);
                }
                return true;
            } finally {
                lock.unlock();
            }
        }

        public int size() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                return size;
            } finally {
                lock.unlock();
            }
        }

        public boolean isEmpty() {
            return size() == 0;
        }

        public int remainingCapacity() {
            return Integer.MAX_VALUE;
        }

        public RunnableScheduledFuture<?> peek() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                return queue[0];
            } finally {
                lock.unlock();
            }
        }

        public boolean offer(Runnable x) {
            if (x == null)
                throw new NullPointerException();
            RunnableScheduledFuture<?> e = (RunnableScheduledFuture<?>)x;
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                int i = size;
                if (i >= queue.length)
                    grow();
                size = i + 1;
                if (i == 0) {
                    queue[0] = e;
                    setIndex(e, 0);
                } else {
                    siftUp(i, e);
                }
                if (queue[0] == e) {
                    leader = null;
                    available.signal();
                }
            } finally {
                lock.unlock();
            }
            return true;
        }

        public void put(Runnable e) {
            offer(e);
        }

        public boolean add(Runnable e) {
            return offer(e);
        }

        public boolean offer(Runnable e, long timeout, TimeUnit unit) {
            return offer(e);
        }

        /**
         * Performs common bookkeeping for poll and take: Replaces
         * first element with last and sifts it down.  Call only when
         * holding lock.
         * @param f the task to remove and return
         */
        private RunnableScheduledFuture<?> finishPoll(RunnableScheduledFuture<?> f) {
            int s = --size;
            RunnableScheduledFuture<?> x = queue[s];
            queue[s] = null;
            if (s != 0)
                siftDown(0, x);
            setIndex(f, -1);
            return f;
        }
        //任务出列,没哟返回空
        public RunnableScheduledFuture<?> poll() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                RunnableScheduledFuture<?> first = queue[0];
                if (first == null || first.getDelay(NANOSECONDS) > 0)
                    return null;
                else
                    return finishPoll(first);
            } finally {
                lock.unlock();
            }
        }

         //弹出任务,没有阻塞
        public RunnableScheduledFuture<?> take() throws InterruptedException {
            final ReentrantLock lock = this.lock;
            lock.lockInterruptibly();
            try {
                for (;;) {
                    RunnableScheduledFuture<?> first = queue[0];
                    if (first == null)
                        available.await();
                    else {
                        long delay = first.getDelay(NANOSECONDS);
                        if (delay <= 0) //小于0 立马出列,被执行
                            return finishPoll(first);
                        first = null; // don't retain ref while waiting
                        if (leader != null) //leader !=null,说明有线程在等待
                            available.await();
                        else { //为空,说明没有线程在等待
                            Thread thisThread = Thread.currentThread();
                            leader = thisThread;
                            try {
                                available.awaitNanos(delay); //等待指定时间后苏醒
                            } finally {
                                if (leader == thisThread) //leader等于当前线程,当前线程执行完成后,应将leader置为空
                                    leader = null;
                            }
                        }
                    }
                }
            } finally {
                if (leader == null && queue[0] != null) 
                    available.signal(); //唤醒标志
                lock.unlock();
            }
        }

        public RunnableScheduledFuture<?> poll(long timeout, TimeUnit unit)
            throws InterruptedException {
            long nanos = unit.toNanos(timeout);
            final ReentrantLock lock = this.lock;
            lock.lockInterruptibly();
            try {
                for (;;) {
                    RunnableScheduledFuture<?> first = queue[0];
                    if (first == null) {
                        if (nanos <= 0)
                            return null;
                        else
                            nanos = available.awaitNanos(nanos);
                    } else {
                        long delay = first.getDelay(NANOSECONDS);
                        if (delay <= 0)
                            return finishPoll(first);
                        if (nanos <= 0)
                            return null;
                        first = null; // don't retain ref while waiting
                        if (nanos < delay || leader != null)
                            nanos = available.awaitNanos(nanos);
                        else {
                            Thread thisThread = Thread.currentThread();
                            leader = thisThread;
                            try {
                                long timeLeft = available.awaitNanos(delay);
                                nanos -= delay - timeLeft;
                            } finally {
                                if (leader == thisThread)
                                    leader = null;
                            }
                        }
                    }
                }
            } finally {
                if (leader == null && queue[0] != null)
                    available.signal();
                lock.unlock();
            }
        }

        public void clear() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                for (int i = 0; i < size; i++) {
                    RunnableScheduledFuture<?> t = queue[i];
                    if (t != null) {
                        queue[i] = null;
                        setIndex(t, -1);
                    }
                }
                size = 0;
            } finally {
                lock.unlock();
            }
        }

        /**
         * Returns first element only if it is expired.
         * Used only by drainTo.  Call only when holding lock.
         */
        private RunnableScheduledFuture<?> peekExpired() {
            // assert lock.isHeldByCurrentThread();
            RunnableScheduledFuture<?> first = queue[0];
            return (first == null || first.getDelay(NANOSECONDS) > 0) ?
                null : first;
        }

        public int drainTo(Collection<? super Runnable> c) {
            if (c == null)
                throw new NullPointerException();
            if (c == this)
                throw new IllegalArgumentException();
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                RunnableScheduledFuture<?> first;
                int n = 0;
                while ((first = peekExpired()) != null) {
                    c.add(first);   // In this order, in case add() throws.
                    finishPoll(first);
                    ++n;
                }
                return n;
            } finally {
                lock.unlock();
            }
        }

        public int drainTo(Collection<? super Runnable> c, int maxElements) {
            if (c == null)
                throw new NullPointerException();
            if (c == this)
                throw new IllegalArgumentException();
            if (maxElements <= 0)
                return 0;
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                RunnableScheduledFuture<?> first;
                int n = 0;
                while (n < maxElements && (first = peekExpired()) != null) {
                    c.add(first);   // In this order, in case add() throws.
                    finishPoll(first);
                    ++n;
                }
                return n;
            } finally {
                lock.unlock();
            }
        }

        public Object[] toArray() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                return Arrays.copyOf(queue, size, Object[].class);
            } finally {
                lock.unlock();
            }
        }

        @SuppressWarnings("unchecked")
        public <T> T[] toArray(T[] a) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                if (a.length < size)
                    return (T[]) Arrays.copyOf(queue, size, a.getClass());
                System.arraycopy(queue, 0, a, 0, size);
                if (a.length > size)
                    a[size] = null;
                return a;
            } finally {
                lock.unlock();
            }
        }

        public Iterator<Runnable> iterator() {
            return new Itr(Arrays.copyOf(queue, size));
        }

        /**
         * Snapshot iterator that works off copy of underlying q array.
         */
        private class Itr implements Iterator<Runnable> {
            final RunnableScheduledFuture<?>[] array;
            int cursor = 0;     // index of next element to return
            int lastRet = -1;   // index of last element, or -1 if no such

            Itr(RunnableScheduledFuture<?>[] array) {
                this.array = array;
            }

            public boolean hasNext() {
                return cursor < array.length;
            }

            public Runnable next() {
                if (cursor >= array.length)
                    throw new NoSuchElementException();
                lastRet = cursor;
                return array[cursor++];
            }

            public void remove() {
                if (lastRet < 0)
                    throw new IllegalStateException();
                DelayedWorkQueue.this.remove(array[lastRet]);
                lastRet = -1;
            }
        }
    }
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值