JUC并发编程——BlockingQueue阻塞队列

本文详细介绍了Java并发编程中BlockingQueue的概念及其实现原理。探讨了其在多线程环境中的作用,特别是如何通过队列实现线程间的高效数据共享。同时,文章还列举了几种常用的BlockingQueue类型,并通过示例代码展示了四种不同场景下的队列操作。

JUC并发编程——BlockingQueue阻塞队列

1、BlockingQueue 简介

BlockingQueue:阻塞队列,遵循FIFIO(先进先出)

BlockingQueue 提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。

多线程环境中,通过队列可以很容易实现数据共享,比如经典的“生产者”和“消费者”模型中,通过队列可以很便利地实现两者之间的数据共享。生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。

2、BlockingQueue 继承关系

BlockingQueue是 java.util.concurrent 包里的一个接口, 继承Queue接口,Queue接口继承 Collection,Set 和 List 也继承与Collection,BlockingQueue 继承关系如下图:

在这里插入图片描述

Deque:双端队列,是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。

LinkedBlockingQueue 是一个基于链表实现的可选容量的阻塞队列。如果在初始化时没有指定容量,那么默认使用int的最大值作为队列容量。队头的元素是插入时间最长的,队尾的元素是最新插入的。新的元素将会被插入到队列的尾部。

ArrayBlockingQueue 底层是使用一个数组实现队列的,并且在构造ArrayBlockingQueue时需要指定容量,也就意味着底层数组一旦创建了,容量就不能改变了,因此ArrayBlockingQueue是一个容量限制的阻塞队列。因此,在队列全满时执行入队将会阻塞,在队列为空时出队同样将会阻塞。

3、BlockingQueue 四组API

1、抛出异常

    public static void test1(){
        //创建一个大小为3的数组阻塞队列
        ArrayBlockingQueue<Object> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        //添加元素
        System.out.println(arrayBlockingQueue.add("a"));//true
        System.out.println(arrayBlockingQueue.add("b"));
        System.out.println(arrayBlockingQueue.add("c"));
//      System.out.println(arrayBlockingQueue.add("d"));//添加失败,抛出异常 Queue full

        System.out.println(arrayBlockingQueue.element());//取出队首元素

        //取出元素
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
    }

2、不抛异常,有返回值

public static void test2(){
    //创建一个大小为3的数组阻塞队列
    ArrayBlockingQueue<Object> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
    //添加元素
    System.out.println(arrayBlockingQueue.offer("a"));//true
    System.out.println(arrayBlockingQueue.offer("b"));
    System.out.println(arrayBlockingQueue.offer("c"));
    System.out.println(arrayBlockingQueue.offer("d"));//添加失败,返回false

    System.out.println(arrayBlockingQueue.peek());//取出队首元素

    //取出元素
    System.out.println(arrayBlockingQueue.poll());
    System.out.println(arrayBlockingQueue.poll());
    System.out.println(arrayBlockingQueue.poll());
}

3、一直等待

    public static void test3() throws InterruptedException {
        //创建一个大小为3的数组阻塞队列
        ArrayBlockingQueue<Object> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        //添加元素
        arrayBlockingQueue.put("a");//true
        arrayBlockingQueue.put("b");
        arrayBlockingQueue.put("c");
        arrayBlockingQueue.put("d");//添加失败,程序会一直等待


        //取出元素
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
    }

4、超时等待

public static void test4() throws InterruptedException {
    //创建一个大小为3的数组阻塞队列
    ArrayBlockingQueue<Object> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
    //添加元素
    System.out.println(arrayBlockingQueue.offer("a"));//true
    System.out.println(arrayBlockingQueue.offer("b"));
    System.out.println(arrayBlockingQueue.offer("c"));
    System.out.println(arrayBlockingQueue.offer("d",3, TimeUnit.SECONDS));//等待3秒钟,如果添加失败,返回false,程序结束

    System.out.println(arrayBlockingQueue.peek());//取出队首元素

    //取出元素
    System.out.println(arrayBlockingQueue.poll());
    System.out.println(arrayBlockingQueue.poll());
    System.out.println(arrayBlockingQueue.poll());
    System.out.println(arrayBlockingQueue.poll(3, TimeUnit.SECONDS));//等待3秒钟,如果取出失败,返回null,程序结束
}

四组API总结:

方式抛出异常不抛异常,有返回值一直等待超时等待
添加add()offer()put()offer(E e, long timeout, TimeUnit unit)
移除remove()poll()take()poll(long timeout, TimeUnit unit)
查看队首元素element()peek()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万里顾—程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值