Java中的阻塞队列基础

Java中的阻塞队列基础

阻塞队列可以用于线程之间的通信,实现线程与线程之间的解耦。可用于简单的单服务中生成者消费者模式。

使用案例

模拟场景

发布重要通知后,需要进行钉钉消息通知

image-20200921143750420

但实际上,这样会带来一些问题

  1. 正常发布通知接口只需要1s,添加发送钉钉消息逻辑后,变成了2s,效率下降。
  2. 强耦合,正常发布新闻通知,发送钉钉消息不是必须的过程,发送钉钉消息失败会导致发布通知失败。

原代码

public class NewsController {

    public News push(String content){
        News news = new News();
        news.setTitle("content");
        news.setContent("content");
        System.out.println("发布新闻:" + content);
        ddMsg(content);
        return news;
    }

    public void ddMsg(String msg){
        System.out.println("发送钉钉消息:" + msg);
    }

    public static void main(String[] args) {
        NewsController newsController = new NewsController();
        newsController.push("新闻1");
    }

}

改造后先将消息推送到阻塞队列中,在从阻塞队列中获取到数据后,进行钉钉消息的发送,实现发布通知和发送钉钉消息的解耦。

image-20200921145307573

改造后代码

public class NewsController {

    private static ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(10);

    private static boolean isRunning = true;

    public News push(String content) throws InterruptedException {
        News news = new News();
        news.setTitle("content");
        news.setContent("content");
        System.out.println("发布新闻:" + content);
        blockingQueue.put(content);
        return news;
    }

    public void ddMsg(String msg){
        System.out.println("发送钉钉消息:" + msg);
    }

    public static void main(String[] args) throws InterruptedException {
        NewsController newsController = new NewsController();

        new Thread(()->{
            while (isRunning){
                try {
                    newsController.ddMsg(blockingQueue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        for (int i = 0; i < 11; i++) {
            newsController.push("新闻" + i);
            Thread.sleep(2000);
        }


    }

}

JUC中的阻塞队列

队列作用
ArrayBlockingQueue数组实现的阻塞队列,按照FIFO原则对元素进行排序
LinkedBlockingQueue链表实现的有界阻塞队列,默认和最大长度都为Integer.MAX_VALUE。此队列按照FIFO排序
PriorityBlockingQueue支持优先级排序,也可以自定义类实现CompareTo()方法指定排序规则
DelayQueue优先级队列实现的无界阻塞队列
SynchronousQueue不存储元素的阻塞队列,每一个put都必须等待有个take操作
LinkedTransferQueue链表实现的无界阻塞队列
LinkedBlockingDeque链表实现的双向阻塞队列

阻塞队列的基本操作方法

插入操作

  1. add 添加元素到队列,队列满了,继续插入抛异常
  2. offer 添加元素到队列,返回添加状态
  3. put 当队列满了后继续添加,生产者线程会被阻塞一定的时间,如果超时,则线程直接退出

移除操作

  1. remove 队列为空返回false ,移除成功返回true
  2. poll 队列中存在元素,则取出一个元素,为空则返回false,可设置等待时间
  3. take 基于阻塞的方式返回队列中的元素,如果队列为空,则take方法会一直阻塞,直到队列中有新数据可以消费
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值