乐趣区

关于spring:java并发编程工具类JUC第三篇DelayQueue延时队列

DelayQueue 是 BlockingQueue 接口的实现类,它依据 ” 延时工夫 ” 来确定队列内的元素的解决优先级(即依据队列元素的“延时工夫”进行排序)。另一层含意是只有那些超过“延时工夫”的元素能力从队列外面被拿进去进行解决。

  • DelayQueue 队列将阻止其元素对象从队列中被取出,直到达到为元素对象设置的延迟时间。DelayQueue 在队列的头部存储最近过期的元素,如果队列内没有元素过期,应用 poll()办法获取队列内的元素将会返回 null。
  • DelayQueue 类及其迭代器实现了 CollectionIterator接口的所有可选办法,但迭代器办法 iterator() 不能保障以特定的程序遍历 DelayQueue 的元素。

  • DelayQueue 不接管 null 元素,DelayQueue 只承受那些实现了 java.util.concurrent.Delayed 接口的对象 ,并将其放入队列内。DelayQueue 通过调用元素对象的 getDelay(TimeUnit) 办法获取该元素残余的“延迟时间”。getDelay() 的 TimeUnit 工夫单位是一个枚举类型:DAYS(天), HOURS(小时), MINUTES(分钟), SECONDS(秒), MILLISECONDS(毫秒), MICROSECONDS(奥妙), NANOSECONDS(纳秒)
public interface Delayed extends Comparable{long getDelay(TimeUnit unit);
}

上面咱们就写一个 java Class 实现 Delayed 接口,只有实现了 Delayed 接口的类对象能力放入 DelayQueue。因为 Delayed 接口继承自 Comparable 接口,所以咱们必须实现 getDelay 办法和 compareTo 办法。

class DelayObject implements Delayed {
    private String name; 
    private long time;   // 延时工夫

    public DelayObject(String name, long delayTime) { 
      this.name = name; 
      this.time = System.currentTimeMillis() + delayTime;} 

   @Override
   public long getDelay(TimeUnit unit) {long diff = time - System.currentTimeMillis(); 
      return unit.convert(diff, TimeUnit.MILLISECONDS); 
   } 

   @Override
   public int compareTo(Delayed obj) {if (this.time < ((DelayObject)obj).time) {return -1;} 
      if (this.time > ((DelayObject)obj).time) {return 1;} 
      return 0; 
   } 

   @Override
   public String toString() {Date date = new Date(time);
     SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

     return "\nDelayObject:{"
       + "name=" + name
       + ", time=" +  sd.format(date)
       + "}";
   } 
} 

测试延时队列 DelayQueue 的应用成果

public class DelayQueueTest {

  @Test
  void testDelayObject() throws InterruptedException {

    // 实例化一个 DelayQueue
    BlockingQueue<DelayObject> DQ = new DelayQueue<>();

    // 向 DelayQueue 增加四个元素对象,留神延时工夫不同
    DQ.add(new DelayObject("A", 1000 * 10));  // 延时 10 秒
    DQ.add(new DelayObject("B", 4000 * 10));  // 延时 40 秒
    DQ.add(new DelayObject("C", 3000 * 10));  // 延时 30 秒
    DQ.add(new DelayObject("D", 2000 * 10));  // 延时 20 秒

    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // 将对象从 DelayQueue 取出,留神取出的程序与延时工夫无关
    System.out.println(DQ.take());  // 取出 A
    System.out.println(DQ.take());  // 取出 D
    System.out.println(DQ.take());  // 取出 C
    System.out.println(DQ.take());  // 取出 B

  }
}

从上面的打印后果及上文的代码能够看出

  • 队列中元素放入的程序是 A、B、C、D,取出的程序是 A、D、C、B,这是因为队列中的元素依照延时工夫进行了排序。
  • 另外咱们能够看到,每隔 10 秒才能够从队列中取出一个元素,这是因为只有超过“延时工夫”的元素能力从队列外面被拿进去。而咱们设置的延时工夫是 10s、20s、30s、40s。
DelayObject:{name=A, time=2021-03-23 14:14:20}

DelayObject:{name=D, time=2021-03-23 14:14:30}

DelayObject:{name=C, time=2021-03-23 14:14:40}

DelayObject:{name=B, time=2021-03-23 14:14:50}

欢送关注我的博客,外面有很多精品合集

本文转载注明出处(必须带连贯,不能只转文字):字母哥博客 – zimug.com

感觉对您有帮忙的话,帮我点赞、分享!您的反对是我不竭的创作能源!。另外,笔者最近一段时间输入了如下的精品内容,期待您的关注。

  • 《手摸手教你学 Spring Boot2.0》
  • 《Spring Security-JWT-OAuth2 一本通》
  • 《实战前后端拆散 RBAC 权限管理系统》
  • 《实战 SpringCloud 微服务从青铜到王者》
  • 《VUE 深入浅出系列》
退出移动版