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接口的对象,其中的对象只能在其到期时才能从队列中取走. ...
随机推荐
- 160801、BlockingQueue处理多线程
前面介绍过spring的taskExecutor,今天介绍一个jdk里处理多线程的方法 一.spring的配置文件(注入bean) <bean id="cmsClickButtonMn ...
- 深度扫盲O2O
http://www.ftchinese.com/interactive/5038?i=3 http://www.ftchinese.com/interactive/5038?i=3
- centos7 Docker Compose 的安装
[root@localhost ~]# curl -L https://github.com/docker/compose/releases/download/1.8.1/docker-compose ...
- emo前端
1 点击按钮可以在form中添加input控件,以name给input编号,然后点击按钮ajax上传表单,在回调函数中弹框显示结果: <form id="newfriends" ...
- python多线程的两种写法
1.一般多线程 import threading def func(arg): # 获取当前执行该函数的线程的对象 t = threading.current_thread() # 根据当前线程对象获 ...
- python数据类型一(重点是字符串的各种操作)
一.python基本数据类型 1,int,整数,主要用来进行数学运算 2,bool,布尔类型,判断真假,True,False 3,str,字符串,可以保存少量数据并进行相应的操作(未来使用频率最高的一 ...
- springboot整合fastjson 将null转成空字符串
/** * @Auther: mxf * @Date: 2019/4/18 09:12 * @Description: */ @Configuration @EnableWebMvc public c ...
- mysql 关于join的总结
本文地址:http://www.cnblogs.com/qiaoyihang/p/6401280.html mysql不支持Full join,不过可以通过UNION 关键字来合并 LEFT JOIN ...
- MSSQL获取昨天,本周,本月。。。
特别说明下:以下统计本周数据时,星期天是作为下周的第一天,而不是本周最后一天,因此你把星期天作为本周最后一天时,你需要在getDate()的基础上减一天,如dateadd('day', -1, get ...
- 35个例子学会find
find的使用格式如下: $ find <指定目录> <指定条件> <指定动作> - <指定目录>: 所要搜索的目录及其所有子目录.默认为当前目录. - ...