zoukankan      html  css  js  c++  java
  • 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);
            }
  • 相关阅读:
    F2E Tool(前端工程师的工具箱)
    SQLServer 语句存档整理
    MySQL DATE_FORMAT() 函数
    sqlserver 自连接 生成一列数据
    mysql存储引擎:InnoDB和MyISAM的差别/优劣评价/评测/性能测试
    好书推荐
    Flashfxp 3.4的注册码
    mysql事务处理
    mysql 时间函数 格式化
    【转】PowerDesigner 中将Comment(注释)及Name(名称)内容互相COPY的VBS代码
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14641699.html
Copyright © 2011-2022 走看看