首页 > 其他分享 >阻塞的队列

阻塞的队列

时间:2023-07-26 12:22:04浏览次数:36  
标签:消费者 队列 元素 阻塞 生产者 线程

BLockingQueue是一个阻塞的队列,最典型的应用场景就是生产者和消费者模式。

生产者和消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此并不直接通信,而是通过阻塞队列进行通信,所以生产者生产完数据后不用等待消费者进行处理,而是直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列中获取数据,阻塞队列就相当于一个缓冲区,平衡生产者和消费者的处理能力。

在Java中她只是一个接口,它的实现类有ArrayBlockingQueue、DelayQueue、 LinkedBlockingDeque、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等。


注意事项:
BlockingQueue不接受null元素。 实现在尝试add 、 put或offer null抛出NullPointerException 。 null值用作标记值以指示poll操作失败。
BlockingQueue可能有容量限制。 在任何给定的时间,它可能有一个remainingCapacity容量,超过该容量就不能put不阻塞的情况下put其他元素。 没有任何内在容量限制的BlockingQueue总是报告Integer.MAX_VALUE的剩余容量。
BlockingQueue实现主要用于生产者-消费者队列,但另外还支持Collection接口。 因此,例如,可以使用remove(x)从队列中remove(x)任意元素。 然而,这样的操作通常执行得不是很有效,并且仅用于偶尔使用,例如当排队的消息被取消时。
BlockingQueue实现是线程安全的。 所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。 然而,大量的Collection操作addAll , containsAll , retainAll和removeAll不一定原子除非在实现中另有规定执行。 因此,例如,在仅添加c某些元素后, addAll©可能会失败(抛出异常)。
使用示例,基于典型的生产者-消费者场景。 请注意,一个BlockingQueue可以安全地与多个生产者和多个消费者一起使用。
1.ArrayBlockingQueue:
由数组支持的有界阻塞队列。 该队列对元素 FIFO(先进先出)进行排序。 队列的头部是在队列中停留时间最长的那个元素。 队列的尾部是在队列中停留时间最短的那个元素。 新元素插入队列尾部,队列检索操作获取队列头部元素。
这是一个经典的“有界缓冲区”,其中一个固定大小的数组保存由生产者插入并由消费者提取的元素。 容量一旦创建,就无法更改。 尝试put元素放入已满队列将导致操作阻塞; 尝试从空队列中take元素也会类似地阻塞。
此类支持用于排序等待生产者和消费者线程的可选公平策略。 默认情况下,不保证此顺序。 但是,在公平性设置为true构造的队列以 FIFO 顺序授予线程访问权限。 公平通常会降低吞吐量,但会减少可变性并避免饥饿。

2.LinkedBlockingQueue:
基于链表实现的有界阻塞队列。 该队列对元素 FIFO(先进先出)进行排序。 队列的头部是在队列中停留时间最长的那个元素。 队列的尾部是在队列中停留时间最短的那个元素。 新元素插入队列尾部,队列检索操作获取队列头部元素。 链接队列通常比基于数组的队列具有更高的吞吐量,但在大多数并发应用程序中的可预测性能较差。

3. DelayQueue
DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。DelayQueue是一个没有大小限制的队列,因此往队列中插入数据的操作(生产者)永远不会被阻塞,而只有获取数据的操作(消费者)才会被阻塞。
使用场景:
  DelayQueue使用场景较少,但都相当巧妙,常见的例子比如使用一个DelayQueue来管理一个超时未响应的连接队列

4.PriorityBlockingQueue
一个无界阻塞队列,它使用与类PriorityQueue相同的排序规则并提供阻塞检索操作。 虽然这个队列在逻辑上是无界的,但由于资源耗尽(导致OutOfMemoryError ),尝试添加可能会失败。 此类不允许null元素。 依赖于自然排序的优先级队列也不允许插入不可比较的对象(这样做会导致ClassCastException )。
此类及其迭代器实现了Collection和Iterator接口的所有可选方法。 方法iterator()提供的 Iterator 和方法spliterator()中提供的spliterator()不能保证以任何特定顺序遍历 PriorityBlockingQueue 的元素。 如果您需要有序遍历,请考虑使用Arrays.sort(pq.toArray()) 。 此外, drainTo方法可用于按优先级顺序删除部分或所有元素,并将它们放置在另一个集合中。
对此类的操作不保证具有相同优先级的元素的顺序。 如果您需要强制排序,您可以定义自定义类或比较器,这些类或比较器使用辅助键来打破主要优先级值之间的联系。 例如,这是一个将先进先出打破平局应用于可比元素的类。 要使用它,您需要插入一个new FIFOEntry(anEntry)而不是一个普通的条目对象。

5.SynchronousQueue
一个阻塞队列,其中每个插入操作都必须等待另一个线程执行相应的移除操作,反之亦然。 同步队列没有任何内部容量,甚至没有容量。 您无法peek同步队列,因为元素仅在您尝试删除它时才存在; 你不能插入一个元素(使用任何方法),除非另一个线程试图删除它; 你不能迭代,因为没有什么可以迭代的。 队列的头部是第一个排队的插入线程试图添加到队列中的元素; 如果没有这样的排队线程,则没有元素可用于删除, poll()将返回null 。 对于其他Collection方法(例如contains ), SynchronousQueue充当空集合。 此队列不允许null元素。
同步队列类似于 CSP 和 Ada 中使用的集合通道。 它们非常适合切换设计,在这种设计中,在一个线程中运行的对象必须与在另一个线程中运行的对象同步,以便将某些信息、事件或任务交给它。
此类支持用于排序等待生产者和消费者线程的可选公平策略。 默认情况下,不保证此顺序。 但是,在公平性设置为true构造的队列以 FIFO 顺序授予线程访问权限

标签:消费者,队列,元素,阻塞,生产者,线程
From: https://www.cnblogs.com/zhc088/p/17582164.html

相关文章

  • MySQL查询阻塞该如何解决
    MySQL是广泛使用的开源数据库管理系统,它提供了方便的查询功能。然而,在高并发访问的情况下,可能出现查询阻塞的情况。下面是一些解决此问题的方法。SHOWFULLPROCESSLIST;可以使用上述命令查看所有正在执行的SQL查询,并查看它们是否阻塞其他查询。如果有查询阻塞了其他查询,可以使......
  • 【学习笔记】单调队列和单调栈
    单调栈以这道题为例:P5788。我们考虑维护一个单调栈,里面存的是下标,使里面的下标对应的元素从栈顶到栈底是单调上升的。我们从\(n\rightarrow1\)枚举\(a_i\)对于每个\(i\),如果栈非空,令栈顶的下标为\(j\),若\(a_j\)不比\(a_i\)大,那么这个栈顶元素由于值又小,位置又靠后,如......
  • php redis消息队列
    1、php如何把key存储在不同的redis分片上2、php怎么查看redis的key3、用phpredis操作redis集群支持publish和subscribe吗4、php2018怎么安装redis5、redis使用php怎么进行更新php如何把key存储在不同的redis分片上php如何把key存储在不同的redis分片上redis集群部署方式......
  • LeetCode 406. 根据身高重建队列
    classSolution{public:structnode{intval;intpre;node*next;node(inta,intb,node*c){val=a;pre=b;next=c;}};voidinsert(node*&head,int......
  • bio、nio、aio,同步和阻塞的区别
    java从程序从网络中读取一组数据,首先从用户态发出IO请求,申请系统调用。操作系统内核收到系统调用,执行对应的IO操作。1.首先由DMA从网卡缓存区将数据拷贝到系统的内核缓冲区。2.再由内核讲内核缓存区的数据拷贝到用户态的用户缓冲区当中。此时,数据拷贝完成依次返回。这个过程中......
  • 6 栈与队列
    栈与队列1栈与队列基础栈:先进后出栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能)。我们常用的SGISTL,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的底层结构。2用栈实现队列题目:......
  • .net消息队列
    .NET消息队列消息队列是一种常用的软件架构模式,可以实现异步通信和解耦合。在分布式系统中使用消息队列可以提高系统的可伸缩性和可靠性。.NET框架提供了一个称为.NET消息队列(.NETMessageQueue,简称MSMQ)的组件,用于在应用程序之间发送消息。什么是.NET消息队列?.NET消息队列是一......
  • 【优先队列】【堆排序实现优先队列】[1054. 距离相等的条形码](https://leetcode.cn/p
    【优先队列】【堆排序实现优先队列】1054.距离相等的条形码在一个仓库里,有一排条形码,其中第i个条形码为barcodes[i]。请你重新排列这些条形码,使其中任意两个相邻的条形码不能相等。你可以返回任何满足该要求的答案,此题保证存在答案。示例1:输入:barcodes=[1,1,1,2,2,2]......
  • day10 栈与队列
    232.用栈实现队列题解:这一题在大学的时候学过,用两个栈来实现队列,队列是先进先出,而栈是先进后出,所以需要两个栈一个用来存队列入队的数据,出队列的时候,需要将顺序调转,这时候就需要用到另一个队列,注意好边界条件就行225.用队列实现栈题解:队列实现栈的功能也不难,主要是想到栈......
  • python 实现队列
    Python实现队列引言在计算机科学中,队列是一种常见的数据结构,用于存储和管理元素。队列采用先进先出(FIFO)的原则,即最先进入队列的元素最先被处理。在Python中,可以使用列表和相关的操作来实现队列。本文将介绍如何使用Python实现队列,并提供详细的代码示例和解释。实现步骤下表展......