DelayQueue的使用

 

    DelayQueue是一个无界阻塞队列,该队列的头部 是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且 poll 将返回 null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于等于 0 的值时,将发生到期。即使无法使用 take 或 poll 移除未到期的元素,也不会将这些元素作为正常元素对待。例如,size 方法同时返回到期和未到期元素的计数。此队列不允许使用 null 元素。

先来看看DelayQueue的定义:

public class DelayQueue<E extends Delayed> extends  AbstractQueue<E>

                                                                       implements BlockingQueue<E>

 

再来看看Delayed,该接口的定义如下:

public interface Delayed extends Comparable<Delayed>

该接口用来标记那些应该在给定延迟时间之后执行的对象。此接口的实现必须定义一个 compareTo 方法,该方法提供与此接口的 getDelay 方法一致的排序。

 

使用例子:

public class SimAlarmDelay implements Delayed{
  public Map<String,String> simAlarm ;
  public long submitNanoTime ;
  
  public SimAlarmDelay(Map<String,String> simAlarm){
       this.simAlarm = simAlarm ;
       this.submitNanoTime = System.nanoTime() ;
  }
  
  /**
   * @param delayTime 延迟时间
   * @param delayTimeUnit 延迟时间对应的时间单位
   * */
  public SimAlarmDelay(Map<String,String> simAlarm,long delayTime,

                                    TimeUnit delayTimeUnit){
       this.simAlarm = simAlarm ;
       //转换为纳秒,并得出延迟到点的纳秒数
       this.submitNanoTime = System.nanoTime() + TimeUnit.NANOSECONDS
                                           .convert(delayTime, delayTimeUnit) ;
  }
  

  @Override
  public int compareTo(Delayed delayed) {
       if(!(delayed instanceof SimAlarmDelay)){
            return 1 ;
       }
       if(this == delayed){
            return 0 ;
       }
       SimAlarmDelay o = (SimAlarmDelay)delayed;
      return submitNanoTime > o.submitNanoTime?1:
                                 (submitNanoTime < o.submitNanoTime ? -1 : 0);
  }

  /**
   * 返回与此对象相关的剩余延迟时间,以给定的时间单位表示。
   * @param unit 时间单位
   * @return 剩余延迟时间;零或负值指示延迟时间已经用尽
   * */
  @Override
  public long getDelay(TimeUnit unit) {
       return unit.convert(submitNanoTime - System.nanoTime(), 

                                                          TimeUnit.NANOSECONDS);
  }
 }

DelayQueue<SimAlarmDelay> simAlarmDelayQueue =

                                                                    new DelayQueue<SimAlarmDelay>() ;

在一个方法中我们可以这样使用:

public void sendSimAlarm(Map<String,String> alarm,

                             long delayTime,TimeUnit delayTimeUnit){
               simAlarmDelayQueue.put(

                                       new SimAlarmDelay(alarm,delayTime,delayTimeUnit));
 }

该方法调用后就立即返回。

 

 然后我们可以开启一个线程来执行其他的业务操作:

new Thread(){
    public void run(){
        while(true){
             try {
                    SimAlarmDelay simAlarmDelay = simAlarmDelayQueue.take() ;

                     //TODO
              } catch (InterruptedException e) {
                    e.printStackTrace();
              }
          }
    }
  }.start();

 

 

 

 

你可能感兴趣的:(DelayQueue,Delayed)