DelayQueue与ProirityBlockingQueue
DelayQueue是一个无界队列,只有在延迟期满的时候,才可以取出元素。该队列的头部存储的延期期满了后保存时间最长的元素。
DelayQueue阻塞队列在我们系统开发中也常常会用到,例如:缓存系统的设计,缓存中的对象,超过了空闲时间,需要从缓存中移出;任务调度系统,能够准确把握任务的执行时间。我们可能需要通过线程处理很多时间上要求很严格的数据,如果使用普通的线程,我们就需要遍历所有的对象,一个一个的检 查看数据是否过期等,首先这样在执行上的效率不会太高,其次就是这种设计的风格也大大的影响了数据的精度。一个需要12:00点执行的任务可能12:01 才执行,这样对数据要求很高的系统有更大的弊端。由此我们可以使用DelayQueue。
为了具有调用行为,存放到DelayDeque的元素必须继承Delayed接口。Delayed接口使对象成为延迟对象,它使存放在DelayQueue类中的对象具有了激活日期。
该接口强制执行下列两个方法。
CompareTo(Delayed o):Delayed接口继承了Comparable接口,该方法是进行队列中元素的排序。
getDelay(TimeUnit unit):这个方法返回到激活日期的剩余时间,时间单位由单位参数指定。
下面给出一个简单的案例,网吧与网民上网,网民交了钱后开始上网,当上网时间到了,网吧结束网民上网。
/**
* 网民实体类
*/
public class Netizen implements Delayed { //身份证
private Long id;
//姓名
private String name;
//上网截至时间
private Long endTime;
//定义时间工具类
private TimeUnit timeUnit = TimeUnit.SECONDS; public Netizen(Long id, String name, Long endTime) {
super();
this.id = id;
this.name = name;
this.endTime = endTime;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getEndTime() {
return endTime;
}
public void setEndTime(Long endTime) {
this.endTime = endTime;
}
//元素相互批较排序
public int compareTo(Delayed o) {
Netizen netizen=(Netizen) o;
return this.getDelay(this.timeUnit)-netizen.getDelay(this.timeUnit)>0?1:0;
}
//判断是否到了截至时间
public long getDelay(TimeUnit unit) { return endTime-System.currentTimeMillis();
}
}
/**
* 网吧实体类
* @author szekinwin
*
*/
public class InternetBar implements Runnable{ private DelayQueue<Netizen> queue=new DelayQueue<Netizen>(); //网民上网
public void startComputer(Long id,String name,int money){ Netizen netizen=new Netizen(id, name, 1000*money+System.currentTimeMillis()); System.out.println("网名"+name+"开始上网计费..."); queue.add(netizen); }
//网民上网时间结束
public void overComputer(Netizen netizen){ System.out.println("网名"+netizen.getName()+"上网时间结束..."); }
//检查上网时间是否到期
public void run() { while(true){
try {
Netizen netizen=queue.take();
overComputer(netizen);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[]args){
InternetBar internatBar=new InternetBar();
//创建三个网民
internatBar.startComputer(1L, "n1", 3);
internatBar.startComputer(2L, "n2", 5);
internatBar.startComputer(3L, "n3", 7);
Thread t1=new Thread(internatBar);
t1.start();
}
}
输出结果如下:

接下来总结一下PriorityBlockingQueue优先级队列,存放在队列中的元素必须实现Comparable接口,重写compareTo()方法。
public class Task implements Comparable<Task>{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int compareTo(Task o) {
return this.id > o.id?1:(this.id < o.id?-1:0);
}
public String toString(){
return this.id + "," + this.name;
}
}
public class PriorityQueueDemo {
public static void main(String[]args) throws InterruptedException{
PriorityBlockingQueue<Task> queue=new PriorityBlockingQueue<Task>();
Task t1=new Task();
t1.setId(5);
t1.setName("p1");
Task t2=new Task();
t2.setId(3);
t2.setName("p2");
Task t3=new Task();
t3.setId(7);
t3.setName("p3");
queue.add(t1);
queue.add(t2);
queue.add(t3);
System.out.println(queue.toString());
System.out.println(queue.take().getId());
}
}
输出结果如下:也就是说队列中的元素是根据元素的ID进行排序的。ID值低的优先级高。

参考网址:http://www.cnblogs.com/wxgblogs/p/5464867.html
DelayQueue与ProirityBlockingQueue的更多相关文章
- Java多线程系列- DelayQueue延时队列
我们在开发中,有如下场景 a) 关闭空闲连接.服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之.b) 缓存.缓存中的对象,超过了空闲时间,需要从缓存中移出.c) 任务超时处理.在网络协议滑动窗 ...
- Java并发之BlockingQueue 阻塞队列(ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue)
package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * Create ...
- 10 DelayQueue 延时队列类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 www.cnblogs.com/oloroso/ 本文由乌合 ...
- DelayQueue
1.结构 使用的是PriorityQueue来作为底层的存储 元素需要实现Delayed接口,该接口继承了comparable接口 DelayQueue的队头元素是根据comparable排在队首的元 ...
- Java多线程之新类库中的构件DelayQueue
DelayQueue 是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的,即队头对象的延迟到期时间最长.注意:不 ...
- 《转》精巧好用的DelayQueue
该文章转自:http://www.cnblogs.com/jobs/archive/2007/04/27/730255.html 我们谈一下实际的场景吧.我们在开发中,有如下场景 a) 关闭空闲连接. ...
- DelayQueue的原理和使用浅谈
在谈到DelayQueue的使用和原理的时候,我们首先介绍一下DelayQueue,DelayQueue是一个无界阻塞队列,只有在延迟期满时才能从中提取元素.该队列的头部是延迟期满后保存时间最长的De ...
- DelayQueue使用
假设现有如下的使用场景: a) 关闭空闲连接.服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之. b) 缓存.缓存中的对象,超过了空闲时间,需要从缓存中移出. c) 任务超时处理.在网络协议滑 ...
- DelayQueue使用示例之KTV包厢记时
在学习Java 多线程并发开发过程中,了解到DelayQueue类的主要作用:是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走. ...
随机推荐
- 【BZOJ4688】One-Dimensional 矩阵乘法
[BZOJ4688]One-Dimensional Description 考虑一个含有 N 个细胞的一维细胞自动机.细胞从 0 到 N-1 标号.每个细胞有一个被表示成一个小于 M 的非负整数的状态 ...
- IE强制不使用兼容模式
[caption id="attachment_471" align="alignnone" width="431"] 强制不使用兼容模式[ ...
- delphi,增删改查问题记录
新增时获取新的主键方法 1.oracle :sys_guid() 写法: 2.sql:pGetGUID 写法: {**************************************** ...
- 巨蟒python全栈开发flask3
首先,我们新建一个项目: 这个时候,我们调用ab函数,可以在所有的模板中使用. 上边是一个特殊装饰器, 1.flask特殊装饰器 下面说几个特殊的装饰器 再请求之前的装饰器 运行: 这个时候,服务端打 ...
- mysql replace 使用注意,update的时候 删除从表数据
使用REPLACE插入一条记录时,如果不重复,REPLACE就和INSERT的功能一样,如果有重复记录,REPLACE就使用新记录的值来替换原来的记录值. 使用REPLACE的最大好处就是可以将DEL ...
- python中counter()记数
一:定义一个list数组,求数组中每个元素出现的次数 如果用Java来实现,是一个比较复杂的,需要遍历数组list. 但是Python很简单:看代码 a = [1,4,2,3,2,3,4,2] fro ...
- 深入理解Java内存模型之系列篇
深入理解Java内存模型(一)——基础 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来 ...
- CCCallFunc, CCCallFuncN, CCCallFuncND 三者的区别
今天学习过程中,自己敲了一个例子,结果在执行Action的时候出现了错误.经排查发现是CCCallFunc使用的问题,应该使用CCCallFuncN,然后搜了下他们的区别,才知道,是因为有一个参数的问 ...
- HttpSession 入门
1. HttpSession 概述 位于 javax.servlet.http 包; HttpSession 是由 JavaWeb 提供的功能, 用来会话跟踪的类, session 是服务器端对象, ...
- 基于vue + typescrpt +vuecli 搭建开发环境
打算学习typeScript与vue集成,先放几个链接,留着自己学习用,后续自己写使用新的~ https://segmentfault.com/a/1190000013676663 https://j ...