原先多线程并发编程的学习笔记和代码整理一下贴上来。
---------------------------------
延迟阻塞队列DelayQueue
根据JDK文档描述:
Delayed元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的Delayed元素。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS)方法返回一个小于等于0的值时,将发生到期。即使无法使用take或poll移除未到期的元素,也不会将这些元素作为正常元素对待。例如,size方法同时返回到期和未到期元素的计数。此队列不允许使用null元素。
因此DelayQueue可以理解为一个使用时间作为比较条件的PriorityBlockingQueue(优先级阻塞队列)。
举个例子:
夏天买来一批食品放入冷藏室,每种食品在冷藏室都有一个保存时间,超过该时间就会变质。食品检查员经常检查食品,超过冷藏时间的食品就要拿出来扔掉。
首先,定义一个食品类:
class Food implements Delayed{ private String foodName; private long saveTime;//保存时间 private long expireTime;//过期时刻=当前时间+保存时间 public Food(String foodName,long saveTime){ this.foodName=foodName; this.saveTime=saveTime; this.expireTime=TimeUnit.NANOSECONDS.convert(saveTime, TimeUnit.SECONDS)+System.nanoTime(); } @Override public int compareTo(Delayed o) { Food that = (Food)o; if(this.expireTime > that.expireTime){//过期时刻越靠后,越排在队尾. return 1; }else if(this.expireTime==that.expireTime){ return 0; }else{ return -1; } } @Override public long getDelay(TimeUnit unit) { return unit.convert(this.expireTime-System.nanoTime(), TimeUnit.NANOSECONDS); } public String getFoodName(){ return this.foodName; } public long getExpireTime(){ return this.expireTime; } public long getSaveTime(){ return this.saveTime; } }
这里,食品类实现了Delayed接口,因此重写了compareTo和getDelay方法。getDelay返回与此对象相关的剩余延迟时间,以给定的时间单位表示。
下面定义一个食品检查员的类:
class FoodChecker implements Runnable{ private DelayQueue<Food> queue; public FoodChecker(DelayQueue<Food> queue){ this.queue=queue; } @Override public void run() { try{ System.out.println("开始检查!"); boolean flag = true; while(flag){ Food food = queue.take();//此处会阻塞,没有时过期食品时不会取出 System.out.println(food.getFoodName()+"食品过期!保存时间:"+food.getSaveTime()+"天."); if(queue.isEmpty()){ flag=false; } } System.out.println("检查完毕!"); }catch(Exception e){ e.printStackTrace(); } } }
食品检查员持有一个DelayQueue,并且不断从该队列中取出过期食品处理掉。
最后,入口函数如下:
DelayQueue<Food> queue=new DelayQueue<Food>(); Random r = new Random(); queue.add(new Food("A", getRandomDay(r))); queue.add(new Food("B", getRandomDay(r))); queue.add(new Food("C", getRandomDay(r))); queue.add(new Food("D", getRandomDay(r))); queue.add(new Food("E", getRandomDay(r))); queue.add(new Food("F", getRandomDay(r))); ExecutorService es = Executors.newSingleThreadExecutor(); es.execute(new FoodChecker(queue)); es.shutdown();
在队列中放入几种食品,并随机给一个保存时间。由于FoodChecker只有一个线程,所以这里使用的是SingleThreadExecutor。
运行结果如下:
开始检查! B食品过期!保存时间:1天. C食品过期!保存时间:2天. A食品过期!保存时间:5天. D食品过期!保存时间:5天. E食品过期!保存时间:6天. F食品过期!保存时间:10天. 检查完毕!
这个例子中使用的是DelayQueue的take方法,该方法获取并移除此队列的头部,在可从此队列获得延迟到期的元素之前会一直等待(即阻塞)。另外,还有几个常用方法如下:
poll():获取并移除此队列的头,如果此队列不包含具有已到期延迟时间的元素,则返回 null。(非阻塞)
peek():获取但不移除此队列的头部;如果此队列为空,则返回 null。与poll不同,如果队列中没有到期元素可用,则此方法返回下一个将到期的元素(如果存在一个这样的元素)。
附:另外一篇不错的文章,一个关于缓存的例子
http://www.cnblogs.com/jobs/archive/2007/04/27/730255.html
相关推荐
在Java的并发编程中,`DelayQueue`是一个非常特殊的队列,它属于并发包`java.util.concurrent`的一部分。`DelayQueue`是一个基于优先级队列(PriorityQueue)实现的无界阻塞队列,它的主要特性是元素只有在达到指定...
4. `DelayQueue`: 一个基于优先级队列的阻塞队列,元素只有在其延迟时间到期后才能被获取。 **阻塞栈(BlockingDeque)** 阻塞栈,即阻塞双端队列(BlockingDeque),在Java中由`LinkedBlockingDeque`实现。它同时...
4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 PriorityBlockingQueue 7. 同步队列 Synchronou sQueue 8. 阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 ...
4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 PriorityBlockingQueue 7. 同步队列 SynchronousQueue 8. 阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 LinkedBlockingDeque ...
延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 PriorityBlockingQueue 7. 同步队列 SynchronousQueue 8. 阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 LinkedBlockingDeque 10...
5. DelayQueue:一个基于PriorityQueue实现的延迟队列,其中的元素只有在过了一定的延迟时间后才能被取走。 6. LinkedTransferQueue和LinkedBlockingDeque:分别为基于链表结构的无界队列,前者提供了多种线程间交换...
4. **DelayQueue**:基于优先级队列实现的无界阻塞队列,主要用于处理延迟过期的对象。 5. **SynchronousQueue**:不存储元素的阻塞队列,每次插入必须等待一次移除,反之亦然。 6. **LinkedTransferQueue**:基于...
`DelayQueue`是Java并发库`java.util.concurrent`中的一个数据结构,它是一个基于优先级队列的无界阻塞队列,可以用于存储具有延迟时间的元素。而Redis则是一个高性能的键值数据库,通过其丰富的数据结构和操作,...
4. DelayQueue:无界阻塞队列,元素需具有延迟时间,只有在延迟时间到达后才能被获取。 5. SynchronousQueue:不存储元素的阻塞队列,每次插入或移除都需要匹配的消费操作,常用于线程池的工作队列。 6. ...
Java并发编程常见知识点源码集锦,涉及到对象锁,Executors多任务线程框架,线程池等示例,列出一些源码包中包括的内容: volatile关键字的非原子性、volatile关键字的使用、AtomicInteger原子性操作、线程安全小...
数组阻塞队列ArrayBlockingQueue,延迟队列DelayQueue, 链阻塞队列 LinkedBlockingQueue,具有优先级的阻塞队列 PriorityBlockingQueue, 同步队列 SynchronousQueue,阻塞双端队列 BlockingDeque, 链阻塞双端队列 ...
Java并发编程中的阻塞队列是一种特殊的队列数据结构,它在多线程环境中用于高效地协调生产者和消费者的交互。阻塞队列的核心特性在于,当队列为空时,尝试从队列中取出元素的线程会被阻塞,直到有其他线程向队列中...
4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 PriorityBlockingQueue 7. 同步队列 SynchronousQueue 8. 阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 LinkedBlockingDeque ...
总结来说,Delayed接口和DelayQueue是Java并发编程中实现延迟处理的重要工具。Delayed接口定义了延迟时间的获取和比较方法,而DelayQueue则是一个基于这些延迟时间的队列,保证了元素在正确的时间点被处理。通过实际...
它可能包含了上述某一种或多种队列的实现,例如用C++、Java或其他编程语言实现的简单队列、阻塞队列、并发队列等。具体的实现细节需要查看源代码才能得知。 在实际应用中,队列常被用于任务调度、消息传递、网络...
- **DelayQueue**:一个特殊类型的阻塞队列,其中的元素只有在其延迟过期之后才能被取出。 - **LinkedBlockingQueue**:一个无界(实际上有限制,可以通过构造函数设定)的阻塞队列,基于链表实现。 - **...
4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 PriorityBlockingQueue 7. 同步队列 SynchronousQueue 8. 阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 LinkedBlockingDeque ...