DelayQueue 队列

        DelayQueue----一种有序队列,特点就是只有在队列中的元素到期后才能取出。

              1.内存中哪些对象到了超时时间,需要从内存中清除出去。

              2.服务器连接中有哪些连接很长时间未操作,需要关闭这些连接

              3.任务中有哪些到了执行时间,该进行调度了。

简单的方法就是写一个线程不断去检查每一项是否到了时间,但这种方法在队列中的元素非常多的情况下会不准确或太耗费性能,用DelayQueue可完美地解决这个问题。


             马上就要过年了,每次回老家都要悲催地去镇上人挤人的网吧上网。下面就拿这个做个例子:

             假设镇上开了一家无限大的网吧,每人交一块钱可以上一分钟网(过年时的网吧坑爹程度差不多就这样);

             网吧比较老式没有先进的管理系统,为了知道哪个家伙时间到该下机了,老板得一台一台地去看,上网的人一多等老板把整个网吧转一遍有些家伙早超时了,而且老板要一遍一遍地检查也累个半死;

             有一天某个人给老板开发了个简单的程序,这个程序可以自动将上机的人排序,并在恰当的时间告诉老板哪个家伙时间到了。这个程序大概会是这样:

[java]  view plain  copy
  1. public class Wangming implements Delayed {  
  2.   
  3.     private String name;  
  4.     //身份证  
  5.     private String id;  
  6.     //截止时间  
  7.     private long endTime;  
  8.       
  9.     public Wangming(String name,String id,long endTime){  
  10.         this.name=name;  
  11.         this.id=id;  
  12.         this.endTime=endTime;  
  13.     }  
  14.       
  15.     public String getName(){  
  16.         return this.name;  
  17.     }  
  18.       
  19.     public String getId(){  
  20.         return this.id;  
  21.     }  
  22.       
  23.     /** 
  24.      * 用来判断是否到了截止时间 
  25.      */  
  26.     @Override  
  27.     public long getDelay(TimeUnit unit) {  
  28.         // TODO Auto-generated method stub  
  29.         return endTime-System.currentTimeMillis();  
  30.     }  
  31.   
  32.     /** 
  33.      * 相互批较排序用 
  34.      */  
  35.     @Override  
  36.     public int compareTo(Delayed o) {  
  37.         // TODO Auto-generated method stub  
  38.         Wangming jia = (Wangming)o;  
  39.         return endTime-jia.endTime>0?1:0;  
  40.     }  
  41.   
  42. }  

[java]  view plain  copy
  1. public class WangBa implements Runnable {  
  2.   
  3.     private DelayQueue<Wangming> queue = new DelayQueue<Wangming>();  
  4.     public boolean yinye =true;  
  5.       
  6.     public void shangji(String name,String id,int money){  
  7.         Wangming man = new Wangming(name,id,1000*60*money+System.currentTimeMillis());        
  8.         System.out.println("网名"+man.getName()+" 身份证"+man.getId()+"交钱"+money+"块,开始上机...");  
  9.         this.queue.add(man);  
  10.     }  
  11.       
  12.     public void xiaji(Wangming man){  
  13.         System.out.println("网名"+man.getName()+" 身份证"+man.getId()+"时间到下机...");  
  14.     }  
  15.   
  16.     @Override  
  17.     public void run() {  
  18.         // TODO Auto-generated method stub  
  19.         while(yinye){  
  20.             try {  
  21.                 System.out.println("检查ing");  
  22.                 Wangming man = queue.take();  
  23.                 xiaji(man);  
  24.             } catch (InterruptedException e) {  
  25.                 // TODO Auto-generated catch block  
  26.                 e.printStackTrace();  
  27.             }  
  28.         }  
  29.     }  
  30.       
  31.     public static void main(String args[]){  
  32.         try{  
  33.             System.out.println("网吧开始营业");  
  34.             WangBa siyu = new WangBa();  
  35.             Thread shangwang = new Thread(siyu);  
  36.             shangwang.start();  
  37.               
  38.             siyu.shangji("路人甲""123"1);  
  39.             siyu.shangji("路人乙""234"2);  
  40.             siyu.shangji("路人丙""345"1);  
  41.         }  
  42.         catch(Exception ex){  
  43.               
  44.         }  
  45.   
  46.     }  
  47. }  

运行结果:

[html]  view plain  copy
  1. 网吧开始营业  
  2. 检查ing  
  3. 网名路人甲 身份证123交钱1块,开始上机...  
  4. 网名路人乙 身份证234交钱2块,开始上机...  
  5. 网名路人丙 身份证345交钱1块,开始上机...  
  6. 网名路人甲 身份证123时间到下机...  
  7. 检查ing  
  8. 网名路人丙 身份证345时间到下机...  
  9. 检查ing  
  10. 网名路人乙 身份证234时间到下机...  
  11. 检查ing  

从上面的运行结果可以看出,程序并没有一遍一遍地扫描队列中的对象,而是在队列中没有对象符合条件时阻塞。

有了这个程序老板邪恶地笑了,他这下子可以舒舒服服地坑爹了。


至于这个好不好用呢,用过才知道,尤其是在并发量比较大的情况下。

DelayQueue 的内部是一个优先队列,从数据结构上看是一个类有序二叉树:

offer、poll、remove() 和 add------ O(log(n)) 时间;
remove(Object) 和 contains(Object) ------线性时间;
peek、element 和 size-------固定时间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值