阻塞队列BlockingQueue

本文深入探讨了Java中的阻塞队列,它是一种线程安全的数据结构,用于生产者-消费者模式。阻塞队列提供四种API使用方式:抛出异常、返回特殊值、一直阻塞和超时退出。通过ArrayBlockingQueue实例展示了如何在满队列和空队列情况下进行插入和移除操作,并分析了其在多线程环境中的优势,简化了线程同步和唤醒的管理。
摘要由CSDN通过智能技术生成

阻塞队列

阻塞:必须要阻塞、不得不阻塞

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

阻塞队列有两个附加操作

  • 支持阻塞的插入方法,当队列满时,从队列中插入元素会被阻塞,直至队列不满
  • 支持阻塞的移除方法,当队列为空时,获取元素的线程会等待队列变为非空

试图从空的队列中获取元素的线程将会被阻塞,直到其他的线程往空队列里插入元素。
试图向已满的队列中添加元素的线程将会被阻塞,知道其他线程从已满的队列中移除元素。

应用场景

常用于生产者与消费者模式中,生产者是向队列里添加元素的线程,消费者是向队列里移除元素的线程。简单来说,阻塞队列是生产者用来存放元素,消费者用来释放元素的容器

阻塞队列的用处

在多线程领域:所谓阻塞,在某些情况下会挂起线程(即阻塞),一旦条件满足,被挂起的线程又会自动被唤起。
为什么需要 BlockingQueue?
好处是我们不需要关心什么时候需要阻塞线程,什么时候需要唤醒线程,因为这一切BlockingQueue 都给你一手包办了。在 concurrent 包发布以前,在多线程环境下,我们每个程序员都必须自己去控制这些细节,尤其还要兼顾效率和线程安全,而这会给我们的程序带来不小的复杂度。

在这里插入图片描述

  • 四种常用API的使用

抛出异常
插入方法是add() 返回值是boolean
移除方法是remove() 返回值是移除的元素
检查方法是element() 返回值是移除的元素

public class Test2 {
    public static void main(String[] args) {

        //队列大小
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        arrayBlockingQueue.add("a");
        arrayBlockingQueue.add("b");
        arrayBlockingQueue.add("c");
        //java.lang.IllegalStateException: Queue full
        //arrayBlockingQueue.add("d");

        //检测队列首元素
        System.out.println("检测队列首元素:"+arrayBlockingQueue.element());
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
        //java.util.NoSuchElementException
        //System.out.println(arrayBlockingQueue.remove());

    }
}

返回特殊值
插入方法offer() 返回值是boolean
移除方法poll() 返回值是移除的元素
检查方法peek()

public class Test2 {
    public static void main(String[] args) {

        //队列大小
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        arrayBlockingQueue.offer("a");
        arrayBlockingQueue.offer("b");
        arrayBlockingQueue.offer("c");
        arrayBlockingQueue.offer("d");//不会出现异常


        //检测队列首元素
        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());//查询出来的是null,不会出现异常
    }
}

一直阻塞
插入方法 put(e)
移除方法 take()
检查方法 不可用

public class Test2 {
    public static void main(String[] args) throws InterruptedException {

        //队列大小
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        arrayBlockingQueue.put("a");
        arrayBlockingQueue.put("b");
        arrayBlockingQueue.put("c");
        //arrayBlockingQueue.put("d");//这一行一直阻塞,下面的移除代码也不能执行。

        //移除元素
        System.out.println(arrayBlockingQueue.take());//a
        System.out.println(arrayBlockingQueue.take());//b
        System.out.println(arrayBlockingQueue.take());//c
        System.out.println(arrayBlockingQueue.take());//阻塞不停止等待
    }
}

超时退出
插入方法 offer(e,time,unit)
poll(time,unit)
不可用

public class Test2 {
    public static void main(String[] args) throws InterruptedException {

        //队列大小
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        arrayBlockingQueue.offer("a");
        arrayBlockingQueue.offer("b");
        arrayBlockingQueue.offer("c");
        //超时等待3秒自动退出,执行下面代码
        arrayBlockingQueue.offer("d",3,TimeUnit.SECONDS);

        //移除元素
        System.out.println(arrayBlockingQueue.poll());//a
        System.out.println(arrayBlockingQueue.poll());//b.poll()
        //阻塞,不停止等待,
        System.out.println(arrayBlockingQueue.poll(3,TimeUnit.SECONDS));
        System.out.println(arrayBlockingQueue.poll());//c
    }
}

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值