JDK之延时任务

JDK中延时任务可以使用

ScheduledThreadPoolExecutor.schedule 方法,其实这个方法和普通的线程池ThreadPoolExecutorService没啥区别,唯一的区别就是BlockingQueue
ScheduledThreadPoolExecutor使用的是它的内部类 
static class DelayedWorkQueue extends AbstractQueue<Runnable>
        implements BlockingQueue<Runnable> {

  

  奥秘其实就在这个DelayQueue的take方法里

  

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)
                            return finishPoll(first);
                        first = null; // don't retain ref while waiting
                        if (leader != null)
                            available.await();
                        else {
                            Thread thisThread = Thread.currentThread();
                            leader = thisThread;
                            try {
                                available.awaitNanos(delay);
                            } finally {
                                if (leader == thisThread)
                                    leader = null;
                            }
                        }
                    }
                }
            } finally {
                if (leader == null && queue[0] != null)
                    available.signal();
                lock.unlock();
            }
        }

其中 

private final Condition available = lock.newCondition(); 
之前的文章分析过,DelayQueue里的元素不是普通的元素,而是必须实现了Delay接口的Class,接口方法是getDelay
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);
        }
原文地址:https://www.cnblogs.com/juniorMa/p/14641699.html