阻塞队列和生产者-消费者模式

  阻塞队列提供了可阻塞的put和take方法。如果队列满了put将阻塞到有空间可用,如果队列为空,take将阻塞到有元素可用。队列可以是有界和无界的,无界的队列put将不会阻塞。

  阻塞队列支持生产者消费者模式,该模式将找出需要完成的工作,和执行工作分开。生产者-消费者模式能简化开发过程,因为消除了生产者和消费者之间的代码依赖性,此外,该模式还将生产数据的过程和使用数据的过程解耦开来。

  在基于阻塞队列构建的生产者-消费者设计中个,当数据生成时,生产者把数据放入队列,当消费者处理数据时,将从队列中获取数据。生产者无需知道消费者的标识和数量,消费者也不需知道生产者是谁。BlockingQueue简化了生产者-消费者设计的实现过程,支持任意数量的生产者和消费者。

  阻塞队列简化了消费者程序的编码,因为take操作会一直阻塞到可用数据。如果生产者生成工作的速率比消费者处理工作的速率快,那么元素会在队列中累计起来,最终耗尽内存。同样put方法的阻塞特性也极大地简化了生产者的编码。如果使用有界队列,当队列充满时,生产者将阻塞并且不能继续生产,消费者就有时间赶上来处理工作。

  阻塞队列同样提供了offer方法,如果数据不能添加到队列中,那么将返回一个失败状态。这样可以用灵活的策略来处理符合过载的情况,如减轻负载,减少生产者数量,增加消费者数量等。

  在构建高可用的程序时,有界队列是一种强大的资源管理工具:能抑制并防止生产过多的工作项,使应用程序在负荷过载的情况下变得更加健壮。

  在类库中,BlockingQueue有多种实现,其中LinkedBlockingQueue和ArrayBlockingQueue是FIFO队列,二者分别和LinkedList和ArrayList类似,但比同步List有更好并发性能。PriorityBlockingQueue是一个按优先级排序的队列,可以按照某种排序而不是FIFO来处理数据,和其他的有序容器一样。还有一个BlockingQueue的实现是SynchronousQueue,实际上维护的不是真正的队列,它不会为队列中元素维护存储空间。它维护一组线程,这些线程在等待着把元素加入或移除队列。其中每个插入操作必须等待另一个线程的对应移除操作,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有。不能在同步队列上进行 peek,因为仅在试图要移除元素时,该元素才存在;除非另一个线程试图移除某个元素,否则也不能(使用任何方法)插入元素;也不能迭代队列,因为其中没有元素可用于迭代。因为同步队列没有存储功能,因此put和take将一直阻塞,直到有另一个线程已准备号参与到交付过程中。仅当有足够多的消费者,并且总有一个消费者准备好获取交付的工作时,才适合使用同步队列。

时间: 2024-12-26 08:20:11

阻塞队列和生产者-消费者模式的相关文章

Java并发(基础知识)—— 阻塞队列和生产者消费者模式

1.阻塞队列 BlockingQueue是线程安全的Queue版本,从它的名字就可以看出,它是一个支持阻塞的Queue实现:当向空BlockingQueue请求数据时,它会阻塞至BlockingQueue非空:当向一个已满BlockingQueue插入数据时,线程会阻塞至BlockingQueue可插入. BlockingQueue 的方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:第一种是抛出一个异常,第二种是返回一个特殊值(null 或 fa

并发编程—— 阻塞队列和生产者-消费者模式

Java并发编程实践 目录 并发编程—— ConcurrentHashMap 并发编程—— 阻塞队列和生产者-消费者模式 概述 第1部分 为什么要使用生产者和消费者模式 第2部分 什么是生产者消费者模式 第3部分 代码示例 第1部分 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据.同样的道理,如果消费者的处理能力大于生产者,那么消费

阻塞队列和生产者-消费者模式、DelayQueue

1.ArrayDeque, (数组双端队列) 2.PriorityQueue, (优先级队列) 3.ConcurrentLinkedQueue, (基于链表的并发队列) 4.DelayQueue,                                         (延期阻塞队列)(阻塞队列实现了BlockingQueue接口) 5.ArrayBlockingQueue,           (基于数组的并发阻塞队列) 6.LinkedBlockingQueue,        (基

Java 并发编程(四)阻塞队列和生产者-消费者模式

阻塞队列 阻塞队列提供了可阻塞的 put 和 take 方法,以及支持定时的 offer 和 poll 方法.如果队列已经满了,那么put方法将阻塞直到有空间可以用:如果队列为空,那么take方法将一直阻塞直到有元素可用.队列可以使有界的,也可以是无界的,无界队列永远都不会充满,因此无界队列上的put方法永远不会阻塞.一种常见的阻塞生产者-消费者模式就是线程池与工作队列的组合,在 Executor 任务执行框架中就体现了这种模式. 意义:该模式能简化开发过程,因为他消除了生产者和消费者类之间的代

阻塞队列实现生产者消费者模式

阻塞队列的特点:当队列元素已满的时候,阻塞插入操作: 当队列元素为空的时候,阻塞获取操作: 生产者线程:Producer 1 package test7; 2 3 import java.util.concurrent.BlockingQueue; 4 5 public class Producer implements Runnable{ 6 7 private final BlockingQueue queue; 8 public Producer(BlockingQueue queue){

使用阻塞队列实现生产者-消费者模型

生产者-消费者模问题 /** * 使用阻塞队列实现生产者-消费者模型 * 阻塞队列只允许元素以FIFO的方式来访问 * @author Bingyue * */ public class ProducerCustomerPattern { public static void main(String[] args) { //生产者和消费者共享的存储区域 BlockingQueue<Integer> blockQueue=new LinkedBlockingQueue(); /** * 此处外部

【译】使用阻塞队列解决生产者-消费者问题

如果你想避免使用错综复杂的wait–notify的语句,BlockingQueue非常有用.BlockingQueue可用于解决生产者-消费者问题,如下代码示例.对于每个开发人员来说,生产者消费者问题已经非常熟悉了,这里我将不做详细描述. 为什么BlockingQueue适合解决生产者消费者问题 任何有效的生产者-消费者问题解决方案都是通过控制生产者put()方法(生产资源)和消费者take()方法(消费资源)的调用来实现的,一旦你实现了对方法的阻塞控制,那么你将解决该问题. Java通过Blo

基于阻塞队列的生产者消费者C#并发设计

这是从上文的<<图文并茂的生产者消费者应用实例demo>>整理总结出来的,具体就不说了,直接给出代码,注释我已经加了,原来的code请看<<.Net中的并行编程-7.基于BlockingCollection实现高性能异步队列>>,我改成适合我的版本了,直接给code: 调用code: static void Main(string[] args) { ProcessQueue<int> processQueue = new ProcessQueu

java ReentrantLock结合条件队列 实现生产者-消费者模式

1 package reentrantlock; 2 3 import java.util.ArrayList; 4 5 public class ProviderAndConsumerTest { 6 7 static ProviderAndConsumer providerAndConsumer = new ProviderAndConsumer(); 8 9 public static void main(String[] args) throws InterruptedException