DelayQueue实际上是一个优先级队列和吴杰的BlockingQueue的聚合体
放入DelayQueue的对象必须实现Delay接口
这个接口有两个方法
一个是
public long getDelay(TimeUnit unit)
只有当这个方法返回的值为0或者是负值的对象才能被take()出来
这个特性很容易和时间关联起来
比如可以这样写
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(time, TimeUnit.MILLISECONDS)-System.nanoTime();
}
time指的是对象的执行时间的时间戳 这样我们就可以控制任务的执行时间了
Delay接口中的另一个方法是
public int compareTo(Delayed o)
这个方法是将对象按优先级排序的基础
下面给个栗子 :
package donar;
import java.util.Date;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* Created by donar on 15/9/8.
*/
public class DelayQueueTest {
public static DelayQueue<MyObject> delayQueue = new DelayQueue<MyObject>();
public static void main(String[] args) {
delayQueue.offer(new MyObject(10000,"o3"));
delayQueue.offer(new MyObject(2000,"o1"));
delayQueue.offer(new MyObject(5000,"o2"));
System.out.println(delayQueue);
new Thread(new TaskDemo()).start();
}
}
class MyObject implements Delayed{
long interval;
String name;
long time;
public MyObject(long interval,String name){
this.interval=interval;
this.name=name;
time=System.currentTimeMillis()+interval;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(time, TimeUnit.MILLISECONDS)-System.nanoTime();
}
@Override
public int compareTo(Delayed o) {
if (this==o){
return 0;
}
long diff=getDelay(TimeUnit.NANOSECONDS)-o.getDelay(TimeUnit.NANOSECONDS);
if(diff>0)return 1;
if(diff<0)return -1;
return 0;
}
public void execute(){
System.out.println(new Date(time) + "---执行了-----" + name + "-----" + interval);
}
@Override
public String toString() {
return name;
}
}
class TaskDemo implements Runnable{
@Override
public void run() {
MyObject object;
try {
while((object=DelayQueueTest.delayQueue.take())!=null){
object.execute();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
output:
[o1, o3, o2]
Tue Sep 08 16:12:20 CST 2015---执行了-----o1-----2000
Tue Sep 08 16:12:23 CST 2015---执行了-----o2-----5000
Tue Sep 08 16:12:28 CST 2015---执行了-----o3-----10000