1.延时队列DealyQueue中要添加的元素必须实现Dealyed接口,并且是重写Dealayed中的getDelay()和compareTo()方法.
2.compareTo()方法的使用可以见我之前的文章,而getDelay方法,如果此方法返回的值小0或者等于0,则消费者线程会从队列中取出此元素,并进行处理。如果getDelay方法返回的值大于0,则消费者线程会wait等待到getDelay方法的值小于0或等于0,再从队列头部取出元素,此时元素应该已经到期。
3.元素Student:
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class Student implements Delayed {
private String name;
private long delayTime;//延迟时间
public Student(String name){
this.name=name;
//随便生成延迟时间(毫秒值)
this.delayTime=System.currentTimeMillis()+TimeUnit.MILLISECONDS.convert((int) (Math.random()*10),TimeUnit.SECONDS);
}
//此方法是用来判断你的元素的延迟时间是到期,从而决定是否能给消费者消费
@Override
public long getDelay(TimeUnit unit) {
//延迟3秒
return delayTime-System.currentTimeMillis();
}
//此方法是根据延迟时间从小到大来排列到队列中的元素
@Override
public int compareTo(Delayed o) {
Student obj=(Student)o;
//优先级比较
if (this.delayTime>obj.delayTime){
return 1;
}else if (this.delayTime<obj.delayTime){
return -1;
}else {
return 0;
}
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", workTime=" + TimeUnit.SECONDS.convert(delayTime,TimeUnit.MILLISECONDS) +'\'' +
",delay="+(System.currentTimeMillis()-delayTime)+
'}';
}
}
4.线程处理DelayQueue:
import java.util.Iterator;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;
public class DelayQueueTest implements Runnable{
private static DelayQueue<Student> students=new DelayQueue<>();
@Override
public void run() {
try {
while (true){
Student take = students.take();
TimeUnit.SECONDS.sleep(2);//假装用2秒来处理该线程
System.out.println(take);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//存入16个元素到队列
for (int i = 0; i <16 ; i++) {
Student student=new Student("宝"+i);
students.add(student);
}
//用1个线程去处理
DelayQueueTest delayQueueTest=new DelayQueueTest();
for (int i = 0; i < 1; i++) {
new Thread(delayQueueTest).start();
}
//用2个线程去处理
DelayQueueTest delayQueueTest=new DelayQueueTest();
for (int i = 0; i < 2; i++) {
new Thread(delayQueueTest).start();
}
}
}
用一个线程去处理队列:
会让后面的元素等待时间超长
而让多个线程处理之后(4个):
基本上是同步处理完所有的元素