java delayqueue_延时队列:Java中的DelayQueue

Java中的DelayQueue位于java.util.concurrent包下,本质是由PriorityQueue和BlockingQueue实现的阻塞优先级队列。

放入队列的元素需要实现java.util.concurrent包的Delayed接口:

public interface Delayed extends Comparable{/*** Returns the remaining delay associated with this object, in the

* given time unit.

*

*@paramunit the time unit

*@returnthe remaining delay; zero or negative values indicate

* that the delay has already elapsed*/

longgetDelay(TimeUnit unit);

}

通过实现这个接口,来完成对队列中元素,按照时间延迟先后排序的目的。

从队列中取元素:

看DelayedQueue的take()方法:

/*** Retrieves and removes the head of this queue, waiting if necessary

* until an element with an expired delay is available on this queue.

*

*@returnthe head of this queue

*@throwsInterruptedException {@inheritDoc}*/

public E take() throwsInterruptedException {final ReentrantLock lock = this.lock;

lock.lockInterruptibly();try{for(;;) {

E first=q.peek();if (first == null)

available.await();else{long delay =first.getDelay(NANOSECONDS);if (delay <= 0)returnq.poll();

first= null; //don't retain ref while waiting

if (leader != null)

available.await();else{

Thread thisThread=Thread.currentThread();

leader=thisThread;try{

available.awaitNanos(delay);

}finally{if (leader ==thisThread)

leader= null;

}

}

}

}

}finally{if (leader == null && q.peek() != null)

available.signal();

lock.unlock();

}

}

可以看到,在这段代码里,在第一个元素的延迟时间还没到的情况下:

如果当前没有其他线程等待,则阻塞当前线程直到延迟时间。

如果有其他线程在等待,则阻塞当前线程。

向队列中放入元素:

/*** Inserts the specified element into this delay queue.

*

*@parame the element to add

*@return{@codetrue}

*@throwsNullPointerException if the specified element is null*/

public booleanoffer(E e) {final ReentrantLock lock = this.lock;

lock.lock();try{

q.offer(e);if (q.peek() ==e) {

leader= null;

available.signal();

}return true;

}finally{

lock.unlock();

}

}

在放入元素的时候,会唤醒等待中的读线程。

如果我们不考虑分布式运行和任务持久化的话,Java中的DelayQueue是一个很理想的方案,精巧好用。但是如果我们需要分布式运行和任务持久化,就需要引入一些外部组件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值