进阶篇:延时队列之DelayQueue(十四)
来源:互联网 发布:知误会前番书语 编辑:程序博客网 时间:2024/06/05 17:04
这篇文章我们来讲讲BlockingQueue阻塞队列的另一个实现DelayQueue,先前我们的文章中有介绍LinkedBlockingQueue,而DelayQueue与之不同的是,DelayQueue里面哪怕有元素也无法取出,除非元素已经到期,而LinkedBlockingQueue只要里面有元素就可以取出!
所以,你可以往DelayQueue中存放一个元素,且声明在半小时后才失效。那么往此队列中取元素的线程将会阻塞半小时,直到半小时后才能拿到元素进行下一步动作,这样的话,你就可以变相实现定时执行任务了;当然,我们是不会这样来用的,定时任务有更完美的解决方案,这个我们后面再介绍;
class DelayTask implements Delayed,Runnable{long trigger = 0;//触发时间,也就是队列中的元素失效时间int id = 0;long delayMilliSecound = 0;//等待时间public DelayTask( long delayMilliSecound,int id) {this.delayMilliSecound = delayMilliSecound;this.trigger = System.currentTimeMillis()+delayMilliSecound;this.id = id;}@Overridepublic int compareTo(Delayed arg) {DelayTask delay = (DelayTask) arg;if(this.trigger==delay.trigger){return 0;}//必须要越晚到期的元素越排后,因为队列是先进先出的,最先弹出的元素是队头,所以队头必须是最先到期的//当然,如果不这样做也不会有任何报错,只是,本来等待3秒某个任务必须要执行了//但由于队头要等待10秒,在队头没有被弹出之前,该任务是无法弹出的;return this.trigger > delay.trigger?1:-1;}//返回与此对象相关的剩余延迟时间,以给定的时间单位表示。@Overridepublic long getDelay(TimeUnit unit) {return unit.convert(trigger-System.currentTimeMillis(), TimeUnit.MILLISECONDS);}@Overridepublic void run() {System.out.println("任务"+id+"开始运行,等待时间为:"+delayMilliSecound);}}
//DelayQueue,存放Delayed元素的一个无界阻塞队列,只有在某个元素的延迟期满时才能从中提取元素,它和LinkedBlockingQueue不同的是,//DelayQueue里面哪怕有元素也无法取出,除非元素已经到期,也就是getDelay()返回值<=0;//而LinkedBlockingQueue只要里面有元素就可以取出!//DelayQueue也可以看成是一个变相的优先级队列;也就是说,越快失效的元素越能优先取出!public static void delayQueue() throws InterruptedException{final DelayQueue<DelayTask> queue = new DelayQueue<DelayTask>();Random random = new Random();for (int i = 0; i < 10; i++) {queue.put(new DelayTask(random.nextInt(5000),i+1));}//开启一个消费者线程消费队列中的任务new Thread(new Runnable() {@Overridepublic void run() {System.out.println("开始消费队列中的任务!");while( !Thread.currentThread().isInterrupted()){try {//取出队列中的元素queue.take().run();} catch (InterruptedException e) {e.printStackTrace();}}}}).start();//等任务全部消费完毕,再往队列里面塞一个ID为100,延期3秒的任务!TimeUnit.MILLISECONDS.sleep(6000);queue.put(new DelayTask(3000, 100));}
注意:DelayQueue中存放的对象必须实现Delayed接口的compareTo方法与getDelay方法!
看一下输出:************************************************************************
开始消费队列中的任务!
任务4开始运行,等待时间为:554
任务9开始运行,等待时间为:729
任务5开始运行,等待时间为:917
任务3开始运行,等待时间为:1079
任务1开始运行,等待时间为:1652
任务10开始运行,等待时间为:2969
任务2开始运行,等待时间为:3676
任务7开始运行,等待时间为:3829
任务6开始运行,等待时间为:4252
任务8开始运行,等待时间为:4294
任务100开始运行,等待时间为:3000
**************************************************************************************
我们先往queue中塞入了十个DelayTask实例,且指定延时时间为随机5000毫秒内, 没错,一切都在我们的预料之中,延时时间越短的线程将先得到执行;
- 进阶篇:延时队列之DelayQueue(十四)
- DelayQueue延时队列的使用
- DelayQueue延时队列的使用
- DelayQueue延时队列操作实例
- 阻塞队列之DelayQueue
- DelayQueue 实现延时消息队列实践
- delayQueue延时队列-模拟简易MQ
- 利用DelayQueue实现延时消息队列(简易版MQ)
- 利用DelayQueue实现延时消息队列(简易版MQ)
- 利用DelayQueue实现延时消息队列(简易版MQ)
- DelayQueue 队列
- DelayQueue 队列
- DelayQueue 队列
- DelayQueue 队列
- DelayQueue 队列
- JDK源码分析之DelayQueue无边界阻塞队列类
- Java 并发 --- 阻塞队列之DelayQueue源码分析
- RabbitMQ学习之延时队列
- wpa_supplicant软件架构分析
- 手把手git教程(01)--安装与环境设置
- 父母有个最简单却又是最难实现的愿望
- vsftpd
- 如何在阿里云上部署PHP后端
- 进阶篇:延时队列之DelayQueue(十四)
- 底层如何操作字符串
- HTML 不缓存 & meta og
- 类和对象
- 11.3.3 RPC调用的实现
- Non-square Equation 数学
- 常用设计模式及其应用场景
- 【bzoj 3512】DZY loves math IV
- hdoj-2099-整除的尾数(解题报告)