当前位置:网站首页 > 编程语言 > 正文

阻塞队列和非阻塞队列(阻塞队列和非阻塞队列的关系)



在这里插入图片描述

1. 什么是阻塞队列?

阻塞队列(BlockingQueue)是一个支持两个附加操作的队列

这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用

阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。

JDK7 提供了 7 个阻塞队列。分别是:

  • ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
  • LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
  • PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
  • DelayQueue:一个使用优先级队列实现的无界阻塞队列。
  • SynchronousQueue:一个不存储元素的阻塞队列。
  • LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
  • LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

Java 5 之前实现同步存取时,可以使用普通的一个集合,然后在使用线程的协作和线程同步可以实现生产者,消费者模式,主要的技术就是用好,wait,notify,notifyAll,sychronized 这些关键字。而在 java 5 之后,可以使用阻塞队列来实现,此方式大大简少了代码量,使得多线程编程更加容易,安全方面也有保障。

BlockingQueue 接口是 Queue 的子接口,它的主要用途并不是作为容器,而是作为线程同步的的工具,因此他具有一个很明显的特性,当生产者线程试图向 BlockingQueue 放入元素时,如果队列已满,则线程被阻塞,当消费者线程试图从中取出一个元素时,如果队列为空,则该线程会被阻塞,正是因为它所具有这个特性,所以在程序中多个线程交替向 BlockingQueue 中放入元素,取出元素,它可以很好的控制线程之间的通信。

阻塞队列使用最经典的场景就是 socket 客户端数据的读取和解析,读取数据的线程不断将数据放入队列,然后解析线程不断从队列取数据解析

2. 阻塞队列的生产者-消费者模式

阻塞队列(Blocking queue)提供了可阻塞的put和take方法,它们与可定时的offer和poll是等价的。如果Queue已经满了,put方法会被阻塞直到有空间可用;如果Queue是空的,那么take方法会被阻塞,直到有元素可用。Queue的长度可以有限,也可以无限;无限的Queue永远不会充满,所以它的put方法永远不会阻塞

阻塞队列支持生产者-消费者设计模式。一个生产者-消费者设计分离了“生产产品”和“消费产品”。该模式不会发现一个工作便立即处理,而是把工作置于一个任务(“to do”)清单中,以备后期处理。生产者-消费者模式简化了开发,因为它解除了生产者和消费者之间相互依赖的代码。生产者和消费者以不同的或者变化的速度生产和消费数据,生产者-消费者模式将这些活动解耦,因而简化了工作负荷的管理。

生产者-消费者设计是围绕阻塞队列展开的,生产者把数据放入队列,并使数据可用,当消费者为适当的行为做准备时会从队列中获取数据。生产者只负责把数据放入队列。类似地,消费者也不需要知道生产者是谁,以及是谁给它们安排的工作。BlockingQueue可以使用任意数量的生产者和消费者,从而简化了生产者-消费者设计的实现。最常见的生产者-消费者设计是将线程池与工作队列相结合

3. 有哪些非阻塞队列?

  • ArrayQueue:数组队列
  • ArrayDeque:数组双端队列
  • PriorityQueue:优先级队列
  • ConcurrentLinkedQueue:基于链表的并发队列

4. 使用阻塞队列和非阻塞队列的生产者-消费者模式代码

场景:1个生产者线程,3个消费者线程,工作队列的大小为2

4.1 阻塞队列(LinkedBlockingQueue实现)
 
  

输出结果:

 
  

可以看出,只有当队列中存在元素,消费者线程才会去队列中取元素,否则将会阻塞,直到队列中生产了元素以后才会继续执行

4.2 非阻塞队列(ConcurrentLinkedQueue实现)
 
  

输出结果:

 
  

使用非阻塞队列,当消费者线程从队列中获取元素,而此时队列为空,则不会阻塞,而是返回null,即获取到null

如果使用ConcurrentLinkedQueue作为生产者-消费者模型的队列使用,应该加上锁的并发控制机制

到此这篇阻塞队列和非阻塞队列(阻塞队列和非阻塞队列的关系)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • flash打包exe(flash打包apk)2025-07-05 17:09:04
  • 圈一怎么用键盘打出来(圈一符号怎么打出来)2025-07-05 17:09:04
  • 虚拟机识别不了u盘(虚拟机识别不了u盘怎么解决)2025-07-05 17:09:04
  • 阻塞队列有哪些(阻塞队列有哪些实现?各有什么优缺点)2025-07-05 17:09:04
  • 学籍认证码在哪里找(学籍认证码如何查询)2025-07-05 17:09:04
  • 圈一圈算一算怎么圈图(除法圈一圈算一算怎么圈图)2025-07-05 17:09:04
  • mt7811原理图(mt7811芯片)2025-07-05 17:09:04
  • ipv4的计算题(ipv4计算方法)2025-07-05 17:09:04
  • ip查域名怎么查(ip查域名怎么查不到)2025-07-05 17:09:04
  • ddp贸易术语解释英文(ddp贸易术语全称)2025-07-05 17:09:04
  • 全屏图片