DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延迟期满时才能从队列中提取元素。我们可以将DelayQueue运用在以下应用场景:
- 缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取元素时,表示缓存有效期到了。
- 定时任务调度。使用DelayQueue保存当天将会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,从比如TimerQueue就是使用DelayQueue实现的。
具有过期时间的缓存
package test; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; public class SessionCache<K, V> { public ConcurrentHashMap<K, V> map = new ConcurrentHashMap<K, V>(); public DelayQueue<DelayedItem<K>> queue = new DelayQueue<DelayedItem<K>>(); static class SingletonHolder { static SessionCache instance = new SessionCache(); } public static SessionCache getInstance() { return SingletonHolder.instance; } public void put(K k, V v, long liveTime) { V v2 = map.put(k, v); DelayedItem<K> tmpItem = new DelayedItem<K>(k, liveTime); if (v2 != null) { queue.remove(tmpItem); } queue.put(tmpItem); } public SessionCache() { Thread t = new Thread() { @Override public void run() { dameonCheckOverdueKey(); } }; t.setDaemon(true); t.start(); } public void dameonCheckOverdueKey() { while (true) { DelayedItem<K> delayedItem = queue.poll(); if (delayedItem != null) { map.remove(delayedItem.getT()); System.out.println(System.nanoTime() + " remove " + delayedItem.getT() + " from cache"); } try { Thread.sleep(300); } catch (Exception e) { // TODO: handle exception } } } public static void main(String[] args) throws InterruptedException { Random random = new Random(); int cacheNumber = 10; Long liveTime = 200000000L; SessionCache cache = SessionCache.getInstance(); for (int i = 0; i < cacheNumber; i++) { liveTime = liveTime + random.nextInt(10) * 10000; System.out.println(i + " " + liveTime); cache.put(i + "", i + "", liveTime); liveTime = 200000000L; } Thread.sleep(100000); System.out.println(); } } class DelayedItem<T> implements Delayed { private T t; private long liveTime; private long removeTime; public DelayedItem(T t, long liveTime) { this.setT(t); this.liveTime = liveTime; this.removeTime = TimeUnit.NANOSECONDS.convert(liveTime, TimeUnit.NANOSECONDS) + System.nanoTime(); } @Override public int compareTo(Delayed o) { if (o == null) return 1; if (o == this) return 0; if (o instanceof DelayedItem) { DelayedItem<T> tmpDelayedItem = (DelayedItem<T>) o; if (liveTime > tmpDelayedItem.liveTime) { return 1; } else if (liveTime == tmpDelayedItem.liveTime) { return 0; } else { return -1; } } long diff = getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS); return diff > 0 ? 1 : diff == 0 ? 0 : -1; } @Override public long getDelay(TimeUnit unit) { return unit.convert(removeTime - System.nanoTime(), unit); } public T getT() { return t; } public void setT(T t) { this.t = t; } @Override public int hashCode() { return t.hashCode(); } @Override public boolean equals(Object object) { if (object instanceof DelayedItem) { return object.hashCode() == hashCode() ? true : false; } return false; } }
参考:http://ifeve.com/java-blocking-queue/
相关推荐
2. 实例化一个DelayQueue,并放入待处理的订单对象。这些订单将在指定的延迟时间后被处理。 3. 使用Jedis或者其他Redis客户端连接到Redis服务器,将订单信息存储为键值对,键是订单号,值是订单数据,同时设置键的...
在Java的并发编程中,`DelayQueue`是一个非常特殊的队列,它属于并发包`java.util.concurrent`的一部分。`DelayQueue`是一个基于优先级队列(PriorityQueue)实现的无界阻塞队列,它的主要特性是元素只有在达到指定...
首先,Java提供了多种方式来实现延迟执行,例如使用`java.util.Timer`类、`java.util.concurrent.DelayQueue`或者`java.util.concurrent.ScheduledExecutorService`。这里我们将重点讨论`ScheduledExecutorService`...
在Java中,`java.util.concurrent`包提供了多种阻塞队列实现,包括`LinkedBlockingQueue`、`ArrayBlockingQueue`、`PriorityBlockingQueue`和`DelayQueue`。 `ArrayBlockingQueue`是一个有界的并发队列,它在创建时...
volatile关键字的非原子性、volatile关键字的使用、AtomicInteger原子性操作、线程安全小例子:多个线程竞争问题、多个线程多个锁问题、创建一个缓存的线程池、多线程使用Vector或者HashTable的示例(简单线程同步...
在这个例子中,使用了`ArrayBlockingQueue`,并且在构造时指定了容量。此外,还可以设置公平性参数,决定线程获取队列元素的策略。如果设置为公平,线程会按照等待时间的长短依次获取元素;非公平模式下,线程获取...
java.util.concurrent包提供了多种BlockingQueue的实现,包括ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue和SynchronousQueue。每个实现都有其特定的用例和特性,例如...
3. 创建DelayQueue实例,`DelayQueue<MyDelayedObject> queue = new DelayQueue();` 4. 将延迟对象添加到队列,`queue.put(new MyDelayedObject());` 5. 从队列中获取并处理元素,`MyDelayedObject obj = queue.take...
#### 整体结构 整个延迟队列由4个部分组成: 1. JobPool用来存放所有Job的元信息。 2. DelayBucket是一组以时间为维度的有序队列,用来存放所有需要延迟的Job(这里只存放Job Id)。 3. Timer负责实时扫描各个...
`BlockingQueue`接口继承自`Queue`接口,提供了多种实现,如`ArrayBlockingQueue`、`DelayQueue`、`LinkedBlockingQueue`、`PriorityBlockingQueue`和`SynchronousQueue`。每个实现都有其特定的特性和使用场景,例如...
- 使用延迟队列实现,存储的是`Delayed`接口的实例。 - 特点:只有当延迟到期时才能从队列中取出元素。 #### 三、如何选用集合? 选择合适的集合类型取决于具体的应用场景和需求: - 当需要快速随机访问元素时...
在这个例子中,生产者线程不断向队列中放入数字,而消费者线程则持续从队列中取出数字,当队列满时,生产者会被阻塞,当队列空时,消费者会被阻塞。这个模型展示了阻塞队列如何有效地协调生产者和消费者的活动。 ...
虽然它们不直接支持定时任务,但可以通过组合使用ScheduledExecutorService和DelayQueue等工具实现定时任务的调度。 在实际应用中,Java定时任务广泛用于数据同步、日志清理、统计分析、系统监控等场景。例如,你...
java队列之queue用法实例分析 java队列之queue用法实例分析主要介绍了java队列之queue用法实例分析,Queue 队列就是一个先入先出(FIFO)的数据结构,Queue接口继承Collection接口。Queue接口与List、Set同一级别,...
Java延迟队列原理与用法实例详解 Java延迟队列是一种特殊的队列结构,它允许元素在队列中等待一段时间,然后才能被消费。在Java中,延迟队列是通过 DelayQueue 实现的,Delayed 接口定义了延迟队列的元素必须实现的...
- 消息队列中间件如RabbitMQ、Kafka等在Java客户端API中也广泛使用`BlockingQueue`进行消息传递。 总之,`BlockingQueue`是Java并发编程的重要工具,它通过简单的API实现了复杂的线程同步和协作,是理解和掌握多...
示例代码展示了如何创建生产者和消费者线程,它们共享同一个 BlockingQueue 实例,通过 `put()` 和 `take()` 方法实现数据的传递。 在 ArrayBlockingQueue 和 LinkedBlockingQueue 的实现中,当队列满时,生产者...
### 高级Java人才培训专家-05-延迟队列精准发布文章 #### 知识点解析 **一、文章定时发布的应用场景与需求** - **背景:** 文章定时发布功能适用于多种场景,如新闻更新、博客发布等。该功能允许作者设定文章的...
下面是一个简单的使用`ArrayBlockingQueue`的例子: ```java import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class BlockingQueueExample { public static...