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);
            }
  • 相关阅读:
    Junit连接oracle数据库
    java判断字符串是否由数字组成
    Hibernate各种主键生成策略与配置详解
    一对多映射关系
    one-to-one 一对一映射关系(转 wq群)
    工厂模式
    struts2
    创建JUtil
    jdbc
    压缩数据
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14641699.html
Copyright © 2011-2022 走看看