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接口的对象,其中的对象只能在其到期时才能从队列中取走. ...
随机推荐
- iOS 断当前时间是否在一天的某个时间段内。
应用中设置一般会存在这样的设置,如夜间勿扰模式,从8:00-23:00,此时如何判断当前时间是否在该时间段内.难点主要在于如何用NSDate生成一个8:00的时间和23:00的时间,然后用当前的时间跟 ...
- 160811、29 个你必须知道的 Linux 命令
虽然Linux发行版支持各种各样的饿GUI(graphical user interfaces),但在某些情况下,Linux的命令行接口(bash)仍然是简单快速的.Bash和 Linux Shell ...
- angular的过滤器
angular有一些自带的过滤器,今天我就来写一下. 首先还是先把导入一个angular插件,再在我们的js中把模块和控制台写上(别忘了在html中写入模块名和在body中写入控制台名,当然控制台名可 ...
- Fluent Ribbon 第六步 StartScreen
上一节,介绍了Toolbar的主要功能,说明了ToolBar的一些最基本用法,这一节,介绍Ribbon的一个重要功能startScreen, startScreen软件第一次启动,呈现的界面. 由于R ...
- Blog上一页和下一页的功能
博客上一页和下一页的功能 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- 几种常见数据库查询判断表和字段是否存在sql
1.MSSQL Server 表:select COUNT(*) from dbo.sysobjectsWHEREname= 'table_name': 字段:select COUNT(*) ...
- phpmail发送邮件
---恢复内容开始--- 首先.需要phpmailer的包. 地址:https://github.com/Synchro/PHPMailer 解开压缩包,将class.phpmailer.php,cl ...
- MAC OSX--docker
http://www.cnblogs.com/yjmyzz/p/docker-install-tutorial.html http://www.cnblogs.com/yjmyzz/p/docker- ...
- SOE不能进入断点调试
一.前言 任何程序开发,如果不能进入断点调试,是非常的痛苦的. 如果有过SOE开发经验的人都知道,SOE开发过程中调试是非常麻烦的.任何在SOE开发模板中的修改都需要重新编译工程,重新生成.soe 文 ...
- 关于java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log
配置JFinal环境时,jar包已导入,web.xml已配置,Config也已经配置好,测试服务器时不停地出现 Exception in thread "main" java.la ...