目录
DelayQueue
DelayQueue存储带激活时间的元素,获取元素的方法会忽略还未到达激活时间的元素。也就是这些激活时间还在未来的元素,对队列是不可见的。使用poll方法会返回null.
- compareTo(Delayed o):继承自Comparable接口。调用该方法的对象延迟值比参数更小,则方法返回负数。大,返回正数。相等,零。
- getDelay(TimeUnit unit):方法返回当前时间与激活时间的差值。TimeUnit是时间的单位。
一、主程序
package xyz.jangle.thread.test.n7_5.delayqueue;
import java.util.Date;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;
/**
* 7.5、使用带延迟元素的线程安全队列
* DelayQueue的元素必须实现Delayed接口
* (Delayed接口继承自Comparable接口,故它也是个优先队列)
*
* Delayed接口需要实现:getDelay方法返回延迟时间。
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年9月13日 下午8:02:58
*
*/
public class M {
public static void main(String[] args) throws Exception {
DelayQueue<Event> queue = new DelayQueue<>();
Thread[] threads = new Thread[5];
for (int i = 0; i < threads.length; i++) {
var task = new Task(i + 1, queue);
threads[i] = new Thread(task);
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
threads[i].join();
}
do {
int counter = 0;
Event event;
do {
event = queue.poll();
if (event != null) {
counter++;
}
} while (event != null);
System.out.println(new Date()+":"+counter+" 。 Size:"+queue.size());
TimeUnit.MILLISECONDS.sleep(500);
} while (queue.size() > 0);
}
}
二、延迟队列的元素类
package xyz.jangle.thread.test.n7_5.delayqueue;
import java.util.Date;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* 延迟队列的元素类
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年9月13日 下午8:03:24
*
*/
public class Event implements Delayed {
private final Date startDate;
public Event(Date startDate) {
super();
this.startDate = startDate;
}
@Override
public int compareTo(Delayed o) {
long result = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
if (result < 0)
return -1;
if (result > 0)
return 1;
return 0;
}
@Override
public long getDelay(TimeUnit unit) {
Date now = new Date();
long diff = startDate.getTime() - now.getTime();
// 由毫秒转换为纳秒
return unit.convert(diff,TimeUnit.MICROSECONDS);
}
}
三、为队列增加元素的类
package xyz.jangle.thread.test.n7_5.delayqueue;
import java.util.Date;
import java.util.concurrent.DelayQueue;
/**
* 为队列增加元素的任务类
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年9月13日 下午8:11:22
*
*/
public class Task implements Runnable {
private final int id;
private final DelayQueue<Event> queue;
public Task(int id, DelayQueue<Event> queue) {
super();
this.id = id;
this.queue = queue;
}
@Override
public void run() {
Date now = new Date();
Date delay = new Date();
delay.setTime(now.getTime() + (id * 1000));
System.out.println("Thread " + id + "," + delay);
for (int i = 0; i < 100; i++) {
Event event = new Event(delay);
queue.add(event);
}
}
}
四、执行结果
Thread 4,Sun Sep 13 20:19:49 CST 2020
Thread 2,Sun Sep 13 20:19:47 CST 2020
Thread 3,Sun Sep 13 20:19:48 CST 2020
Thread 1,Sun Sep 13 20:19:46 CST 2020
Thread 5,Sun Sep 13 20:19:50 CST 2020
Sun Sep 13 20:19:45 CST 2020:0 。 Size:500
Sun Sep 13 20:19:45 CST 2020:0 。 Size:500
Sun Sep 13 20:19:46 CST 2020:100 。 Size:400
Sun Sep 13 20:19:46 CST 2020:0 。 Size:400
Sun Sep 13 20:19:47 CST 2020:100 。 Size:300
Sun Sep 13 20:19:47 CST 2020:0 。 Size:300
Sun Sep 13 20:19:48 CST 2020:100 。 Size:200
Sun Sep 13 20:19:48 CST 2020:0 。 Size:200
Sun Sep 13 20:19:49 CST 2020:100 。 Size:100
Sun Sep 13 20:19:49 CST 2020:0 。 Size:100
Sun Sep 13 20:19:50 CST 2020:100 。 Size:0