DelayQueue 队列

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

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

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

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

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


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

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

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

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

public class Wangming implements Delayed {

	private String name;
	//身份证
	private String id;
	//截止时间
	private long endTime;
	
	public Wangming(String name,String id,long endTime){
		this.name=name;
		this.id=id;
		this.endTime=endTime;
	}
	
	public String getName(){
		return this.name;
	}
	
	public String getId(){
		return this.id;
	}
	
	/**
	 * 用来判断是否到了截止时间
	 */
	@Override
	public long getDelay(TimeUnit unit) {
		// TODO Auto-generated method stub
		return endTime-System.currentTimeMillis();
	}

	/**
	 * 相互批较排序用
	 */
	@Override
	public int compareTo(Delayed o) {
		// TODO Auto-generated method stub
		Wangming jia = (Wangming)o;
		return endTime-jia.endTime>0?1:0;
	}

}

public class WangBa implements Runnable {

	private DelayQueue<Wangming> queue = new DelayQueue<Wangming>();
	public boolean yinye =true;
	
	public void shangji(String name,String id,int money){
		Wangming man = new Wangming(name,id,1000*60*money+System.currentTimeMillis());		
		System.out.println("网名"+man.getName()+" 身份证"+man.getId()+"交钱"+money+"块,开始上机...");
		this.queue.add(man);
	}
	
	public void xiaji(Wangming man){
		System.out.println("网名"+man.getName()+" 身份证"+man.getId()+"时间到下机...");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(yinye){
			try {
				System.out.println("检查ing");
				Wangming man = queue.take();
				xiaji(man);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String args[]){
		try{
			System.out.println("网吧开始营业");
			WangBa siyu = new WangBa();
			Thread shangwang = new Thread(siyu);
			shangwang.start();
			
			siyu.shangji("路人甲", "123", 1);
			siyu.shangji("路人乙", "234", 2);
			siyu.shangji("路人丙", "345", 1);
		}
		catch(Exception ex){
			
		}

	}
}

运行结果:

网吧开始营业
检查ing
网名路人甲 身份证123交钱1块,开始上机...
网名路人乙 身份证234交钱2块,开始上机...
网名路人丙 身份证345交钱1块,开始上机...
网名路人甲 身份证123时间到下机...
检查ing
网名路人丙 身份证345时间到下机...
检查ing
网名路人乙 身份证234时间到下机...
检查ing

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

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


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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值