利用DelayQueue实现延迟任务

DelayQueue是什么

JDK自带DelayQueue 是一个支持延时获取元素的阻塞队列, 内部采用优先队列 PriorityQueue 存储元素,同时元素必须实现 Delayed 接口;在创建元素时可以指定多久才可以从队列中获取当前元素,只有在延迟期满时才能从队列中提取元素。
利用DelayQueue实现延迟任务_第1张图片
DelayQueue属于排序队列,它的特殊之处在于队列的元素必须实现Delayed接口,该接口需要实现compareTo和getDelay方法。
getDelay方法:获取元素在队列中的剩余时间,只有当剩余时间为0时元素才可以出队列。
compareTo方法:用于排序,确定元素出队列的顺序。

实现方法:
1:在测试包jdk下创建延迟任务元素对象DelayedTask,实现compareTo和getDelay方法;
2:在main方法中创建DelayQueue并向延迟队列中添加三个延迟任务;
3:循环的从延迟队列中拉取任务。

package com.dack.test;

import java.util.Calendar;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayedTask implements Delayed {

	public static DelayQueue<DelayedTask> queue;
	
	// 任务的执行时间
	private int executeTime = 0;
	// 业务需要的参数
	private String outStr = "";

	public static void main(String[] args) {
		DelayedTask.queue = new DelayQueue<DelayedTask>();
		// 可有可无
		DelayedTask.queue.add(new DelayedTask(2, "hello"));

		System.out.println(System.currentTimeMillis() + "服务启动");
		while (true) {
			DelayedTask delayedTask = DelayedTask.queue.poll();
			if (delayedTask != null) {
				String os = delayedTask.getOutStr();
				//可以随时添加新的延时任务
				DelayedTask.queue.add(new DelayedTask(2, "hello"));
				
				System.out.println(System.currentTimeMillis() + " 消费服务 ,传参" + os);
			}
		}
	}

	public DelayedTask(int delay) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.SECOND, delay);
		this.executeTime = (int) (calendar.getTimeInMillis());
	}
	
	// 业务所需的参数构造方法
	public DelayedTask(int delay, String str) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.SECOND, delay);
		this.executeTime = (int) (calendar.getTimeInMillis());
		this.outStr = str;
	}

	/**
	 * 元素在队列中的剩余时间
	 * 
	 * @param unit
	 * @return
	 */
	@Override
	public long getDelay(TimeUnit unit) {
		Calendar calendar = Calendar.getInstance();
		return executeTime - (calendar.getTimeInMillis());
	}

	/**
	 * 元素排序
	 * 
	 * @param o
	 * @return
	 */
	@Override
	public int compareTo(Delayed o) {
		long val = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
		return val == 0 ? 0 : (val < 0 ? -1 : 1);
	}

	public int getExecuteTime() {
		return executeTime;
	}

	public void setExecuteTime(int executeTime) {
		this.executeTime = executeTime;
	}

	public String getOutStr() {
		return outStr;
	}

	public void setOutStr(String outStr) {
		this.outStr = outStr;
	}

	
	
}

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