DelayQueue是一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的Delayed 元素。
延迟堵塞队列的实现原理类似于TimerTask。下面假设对超过一定时间的问题的状态修改为实现目标来完成。
以下例子来练习
我们的场景是,1、给一批用户办理业务,按照他们业务量和业务时间排序(就是说剩余办理时间少的优先办理),
2、设置下班时间,下班之后不再办理业务
import org.apache.commons.lang.math.RandomUtils;
import java.util.concurrent.*;
/**
* DelayQueue test
*/
public class ExamTest {
public static void main(String[] args) {
DelayQueue<Task> students = new DelayQueue<>();
int[] time = new int[]{2000,4000,8000};
long openTime = System.currentTimeMillis();
//线程池
Executor e = Executors.newFixedThreadPool(20);
//添加一批顾客
addTask(students,time);
//为顾客办理业务(daemon处理业务)
new Thread(()->{runTask(students,e);}).start();
//下班闹钟
new Thread(()->{openAndClose(openTime);}).start();
}
public static void openAndClose(long openTime) {
while (true){
long op = System.currentTimeMillis() - openTime;
if(op>16000){
System.out.println("营业时间结束,共"+op+"秒,共计"+op/3600+"小时,\n谢谢");
System.exit(0);
}
}
}
public static void addTask(DelayQueue<Task> students,int[] time){
for(int i=0;i<20;i++){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
students.put(new Task(new Student("顾客:"+i+"号" , "办理"+(RandomUtils.nextInt(3)+1)+"项业务!"),time[RandomUtils.nextInt(3)]));
}
}
public static void runTask(DelayQueue<Task> students,Executor exe) {
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Task take = students.take();
StringBuilder sb = new StringBuilder();
sb.append("\n 从").append(take.getNow()).append("开始等候的,");
sb.append("\n 到").append(take.getExpire()).append("办理结束,");
sb.append("\n 共花了").append(take.getDelay()).append("秒,");
sb.append("\n------------------------------");
System.out.println("还有"+students.size()+"个人在排队...");
Student t = (Student) take.getT();
t.setMsg(t.getMsg()+sb.toString());
exe.execute(take.getT());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Data
class Student implements Runnable {
private String name;
private String msg;
public Student(String name, String msg) {
this.name = name;
this.msg = msg;
}
@Override
public void run() {
final StringBuilder sb = new StringBuilder("------------------------------");
sb.append("\n服务信息:");
sb.append("\n").append(name);
sb.append("\n 我总共办理了" ).append(msg);
System.out.println(sb.toString());
}
}
@Data
class Task<T extends Runnable> implements Delayed{
private long expire;
private long delay;
private long now;
private T t;
public Task(T t,long delay) {
this.t = t;
this.delay = delay;
this.now = System.currentTimeMillis();
this.expire = now + delay;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(this.expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
if(o == this){
return 0;
}
if(o instanceof Task){
return this.getDelay(TimeUnit.NANOSECONDS) > ((Task)o).getDelay(TimeUnit.NANOSECONDS) ? 1:-1;
}
return 0;
}
}
本文介绍了一个使用Java并发工具包中的DelayQueue实现的示例程序。该程序模拟了一个业务办理场景,其中用户根据其业务量和业务时间进行排序,并且在设定的营业时间内处理这些请求。
561

被折叠的 条评论
为什么被折叠?



