如何手动实现一个消息队列和延迟消息队列?

如何手动实现一个消息队列和延迟消息队列?

我们可以通过 JDK 提供的 Queue 来实现自定义消息队列,使用 DelayQueue 实现延迟消息队列。

 我们可使用 Queue 来实现消息队列,Queue 大体可分为以下三类:

• **双端队列(Deque)**是 Queue 的子类也是 Queue 的补充类,头部和尾部都支持元素插入和获取;
• 阻塞队列指的是在元素操作时(添加或删除),如果没有成功,会阻塞等待执行,比如当添加元素时,如果队列元素已满,队列则会阻塞等待直到有空位时再插入;
• 非阻塞队列,和阻塞队列相反,它会直接返回操作的结果,而非阻塞等待操作,双端队列也属于非阻塞队列。

Queue 来实现自定义消息队列

/**
 * @author 佛大Java程序员
 * @since 1.0.0
 */
public class CustomQueue {
    /**
     * 定义消息队列
     */
    private static Queue<String> queue = new LinkedList<>();

    public static void main(String[] args) {
        producer();// 调用生产者
        consumer();// 调用消费者
    }

    // 生产者
    public static void producer(){
        // 添加消息
        queue.add("first message.");
        queue.add("second message.");
        queue.add("third message.");
     }

    // 消费者
    public static void consumer(){
        while (!queue.isEmpty()){
        // 消费消息
        System.out.println(queue.poll());
        }
    }

}

运行结果

DelayQueue 实现延迟消息队列

实现自定义延迟队列需要实现 Delayed 接口,重写 getDelay() 方法。

实现 Delayed 接口

/**
 * @author 佛大Java程序员
 * @since 1.0.0
 */
public class MyDelay implements Delayed {

    /**
     * 延迟截止时间(单位:毫秒)
     */
    long delayTime = System.currentTimeMillis();

    private String msg;

    public long getDelayTime() {
        return delayTime;
    }

    public void setDelayTime(long delayTime) {
        this.delayTime = delayTime;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    /**
     * 初始化
     * @param delayTime 设置延迟执行时间
     * @param msg       执行的消息
     */
    public MyDelay(long delayTime, String msg) {
        this.delayTime = (this.delayTime + delayTime);
        this.msg = msg;
    }

    /**
     * 获取剩余时间
     *
     * @param unit
     * @return
     */
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }

    /**
     * 队列里元素的排序依据
     *
     * @param o
     * @return
     */
    @Override
    public int compareTo(Delayed o) {
        if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) {
            return 1;
        } else if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) {
            return -1;
        } else {
            return 0;
        }
    }

   @Override
     public String toString() {
         return this.msg;
     } }

实现类

/**
 * 延迟消息队列
 *
 * @author 佛大Java程序员
 * @since 1.0.0
 */
public class CustomDelayQueue {

    private static DelayQueue delayQueue = new DelayQueue();

    public static void main(String[] args) throws InterruptedException {
        // 调用生产者
        producer();
        // 调用消费者
        consumer();
    }

    /**
     * 生产者
     */
    public static void producer() {
        // 添加消息
        delayQueue.put(new MyDelay(1000, "消息1"));
        delayQueue.put(new MyDelay(3000, "消息2"));
    }

    /**
     * 消费者
     *
     * @throws InterruptedException
     */
    public static void consumer() throws InterruptedException {
        System.out.println("开始执行时间:" +
                DateFormat.getDateTimeInstance().format(new Date()));
        while (!delayQueue.isEmpty()) {
            System.out.println(delayQueue.take());
        }
        System.out.println("结束执行时间:" +
                DateFormat.getDateTimeInstance().format(new Date()));
    }
}

 运行结果

 可以看出,消息 1 和消息 2 都实现了延迟执行3秒的功能。

 

posted @ 2020-05-13 18:03  JustJavaIt  阅读(805)  评论(0编辑  收藏  举报