Java DelayQueue使用实例
程序员文章站
2022-06-30 23:02:15
...
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/
上一篇: jvisualvm下使用JMX方式远程监控tomcat7
下一篇: 霜降吃什么传统食物