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

被折叠的 条评论
为什么被折叠?



