多线程之DelayQueue

来源:互联网 发布:lol美服加速器免费mac 编辑:程序博客网 时间:2024/06/05 16:39

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();            }        }    }}@Dataclass 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());    }}@Dataclass 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;    }}
0 0
原创粉丝点击