也是看了 渴死的火烈鸟 的博客才意识到的。原文http://standalone.iteye.com/blog/1876771

import java.util.concurrent.DelayQueue;

public class DelayQueueExample {
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
        DelayQueue<DelayedElement>  dq=new DelayQueue<DelayedElement>();  
        long now = System.currentTimeMillis();  
        System.out.println("current time in ms: " + now);  
        DelayedElement ob1=new DelayedElement("e1", now + 1000);  
        DelayedElement ob2=new DelayedElement("e2", now + 3000);  
        DelayedElement ob3=new DelayedElement("e3", now + 1500);  
          
        dq.add(ob1);  
        dq.add(ob2);  
        dq.add(ob3);  
          
        try {  
            Thread.sleep(1);  
        } catch (InterruptedException e) {              
            throw new RuntimeException( e );  
        }  
        while(dq.size() > 0){  
            try {  
                DelayedElement e = dq.take();                  
                System.out.println("current time in ms: " + System.currentTimeMillis() + ", element:" + e.name);  
            } catch (InterruptedException e) {                  
                throw new RuntimeException( e );  
            }  
              
        } 
    }
}

DelayQueue源码

public class DelayQueue<E extends Delayed> extends AbstractQueue<E> implements BlockingQueue<E>
public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            for (;;) {
                E first = q.peek();
                if (first == null) {
                    available.await();
                } else {
                    long delay =  first.getDelay(TimeUnit.NANOSECONDS);
                    if (delay > 0) {
                        long tl = available.awaitNanos(delay);
                    } else {
                        E x = q.poll();
                        assert x != null;
                        if (q.size() != 0)
                            available.signalAll(); // wake up other takers
                        return x;

                    }
                }
            }
        } finally {
            lock.unlock();
        }
    }
DelayedElement必须继承Delayed抽象类,并且重写getDelay方法
 1 package com.xqy;
 2 
 3 import java.util.concurrent.Delayed;
 4 import java.util.concurrent.TimeUnit;
 5 
 6 public class DelayedElement implements Delayed {
 7 
 8     public long time;  
 9     public String name;  
10     public DelayedElement(String name, long time){  
11         this.name = name;  
12         this.time = time;  
13     }  
14     @Override  
15     public int compareTo(Delayed o) {  
16         // TODO Auto-generated method stub  
17         if(this.time < ((DelayedElement)o).time) return -1;  
18         else if(this.time > ((DelayedElement)o).time)return 1;  
19         else return 0;  
20     }  
21 
22     @Override  
23     public long getDelay(TimeUnit unit) {  
24         // TODO Auto-generated method stub  
25         long r =  unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS);  
26         System.out.println("delay:" + r);  
27         return r;  
28     }  
29 
30 }

注意上面第25行的方法

unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS)

第一个参数为数字,第二个参数为数字代表的时间单位,这里作为毫秒
执行convert后,返回unit当前的时间单位,此处是纳秒

如果第二个参数写成纳秒,
TimeUnit.NANOSECONDS,则这个转换函数转换前后数值相等,但是DelayQueue的take方法中
if (delay > 0) {
    long tl = available.awaitNanos(delay);
} 

等待的时间将缩短,上面的for循环重复执行将近原来的1000倍。这样会造成CPU空转,是load升高。




posted on 2013-09-30 21:51  xuqiyu  阅读(1484)  评论(0编辑  收藏  举报