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

DelayQueue 是BlockingQueue接口的实现类,它根据"延时时间"来确定队列内的元素的处理优先级(即根据队列元素的“延时时间”进行排序)。另一层含义是只有那些超过“延时时间”的元素才能从队列里面被拿出来进行处理。
- DelayQueue 队列将阻止其元素对象从队列中被取出,直到达到为元素对象设置的延迟时间。DelayQueue 在队列的头部存储最近过期的元素,如果队列内没有元素过期,使用poll()方法获取队列内的元素将会返回null。
 - DelayQueue 类及其迭代器实现了Collection和Iterator接口的所有可选方法,但迭代器方法
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}
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
 
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《手摸手教你学Spring Boot2.0》
 - 《Spring Security-JWT-OAuth2一本通》
 - 《实战前后端分离RBAC权限管理系统》
 - 《实战SpringCloud微服务从青铜到王者》
 - 《VUE深入浅出系列》
 
java并发编程工具类JUC第三篇:DelayQueue延时队列的更多相关文章
- java并发编程工具类JUC第四篇:LinkedBlockingQueue链表队列
		
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue. LinkedBlockingQueue 队列是Blo ...
 - java并发编程工具类JUC第七篇:BlockingDeque双端阻塞队列
		
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
 - java并发编程工具类JUC第八篇:ConcurrentHashMap
		
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
 - java并发编程工具类JUC第一篇:BlockingQueue阻塞队列
		
Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列.换句话说,当多线程同时从 JavaBlocking ...
 - java并发编程工具类JUC第二篇:ArrayBlockingQueue
		
类ArrayBlockingQueue是BlockingQueue接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素.这里的"有界"是指存储容量存在上限,不能无限存储元素. ...
 - Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
		
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...
 - java并发编程工具类辅助类:CountDownLatch、CyclicBarrier和 Semaphore
		
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...
 - 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile
		
章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...
 - Java并发编程入门,看这一篇就够了
		
Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容.这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些都是并发编程的基本知识,除了使用这些工具以外,Java并发编程中涉 ...
 
随机推荐
- 8. vue给标签动态绑定title
			
在利用vue开发时,如果标签宽度比较小,我们需要利用overflow:hidden;text-overflow:ellipsis;white-space: nowrap;对其进行隐藏,但隐藏后如何读其 ...
 - Mybatis3源码笔记(四)Configuration(续)
			
1.pluginElement(root.evalNode("plugins")) 解析plugins节点(注册interceptorChain里记录对应的拦截器) private ...
 - 如何查看显著性SNP在数据中的频率?
			
我们做完GWAS的关联分析后需要查看显著性SNP在我们数据中的频率分布情况.这时候我们需要用到plink和我们做关系分析所用的二进制文件datas. 第一步,我们用R语言读取分析结果,即*.assoc ...
 - Day01_08_变量(Variable)
			
变量 什么是变量? *变量本质上来说是内存上的一块空间,这块空间有数据类型,有名字,有字面值(数据).变量是内存中存储数据最基本的单元 * 变量要求变量中存储的具体数据必须和变量的数据类型一致,必须先 ...
 - 866. Prime Palindrome
			
Find the smallest prime palindrome greater than or equal to N. Recall that a number is prime if it's ...
 - Laravel artisan 命令
			
获取命令列表 php artisan Laravel Framework 7.26.0 Usage: command [options] [arguments] Options: -h, --help ...
 - 【ORM】Mybatis与JPA的区别
			
Mybatis与JPA的区别: 1.ORM映射不同: Mybatis是半自动的ORM框架,提供数据库与结果集的映射: JPA(Hibernate)是全自动的ORM框架,提供对象与数据库的映射: 2.可 ...
 - hdu4279 找规律+小想法
			
题意: 蛋疼的题意,最后是泽神给我讲的题意,题意是对于一个数来说,如果他不能整除另一个数同时他和另一个数非互质,那么另一个数就是这个数的特别数,如10 的特别数有 4 6 8三个,同时题目还 ...
 - 老板让我重构项目,我想首先应该服务治理---eureka服务治理深入浅出
			
目录 什么是服务治理 Eureka调用过程 Eureka单机注册 Eureka 单机启动 单机注册 集群注册 客户调用 Eureka集群注册 idea 如何同一个项目启动多次 Eureka自我保护 为 ...
 - Codeforces Round #712 (Div. 2)
			
A. Déjà Vu 题意:就是问能否加上字母a,使得字符串不中心对称 思路:只有一种情况不能加入,就是全部是a,剩下的都可以满足,找a的位置就找哪个字母不是a,然后让它的对称位置是新加的这个a 代码 ...