Java并发系列9

Wesley13
• 阅读 480

今天要讲的BlockingQueue可谓是大名鼎鼎,在并发编程中比较常见的一个类。

BlockingQueue顾名思义是表示一个阻塞队列,注意这两个词:阻塞和队列。可以拿我们熟悉的生产者-消费者队列来举例,一条流水线上,A生产零件,B组装零件,A就是生产者,B是消费者。如果A生成的太快,则零件堆积,A需要休息一会儿等待B把零件消费完;如果A生产的太慢,则B变得无活可干,被迫休息。

BlockingQueueoffer()put()就是把零件放到队列中,poll()take()就是从队列中取出零件进行消费。需要注意的是put()take()是阻塞方法,而offer()poll()是非阻塞方法,也就是put()的时候队列满了,则阻塞;而offer()的时候队列满了,则返回false,不阻塞。take()poll()方法同理。

BlockingQueue是一个接口,使用起来比较简单。他的实现类如下:
Java并发系列9
比较常用的是ArrayBlockingQueueLinkedBlockingQueue,从名字也可以看出来,ArrayBlockingQueue适合做有界队列,LinkedBlockingQueue适合做无界队列。
这里只看一下简单使用:

        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
        queue.put("abc");
        queue.take();

一般来说put()take()方法会分散在两个或多个线程中。


如果你的好奇心比较重,想研究一下BlockingQueue的实现原理,那么当你看一下ArrayBlockingQueue的源码,就会发现一些有趣的东西:

    /** Main lock guarding all access */
    final ReentrantLock lock;

    /** Condition for waiting takes */
    private final Condition notEmpty;

    /** Condition for waiting puts */
    private final Condition notFull;

啊哈,就是我们前面讲过的ReentrantLockCondition了,请参考:https://my.oschina.net/lizaizhong/blog/1825244

点赞
收藏
评论区
推荐文章
Stella981 Stella981
2年前
Celery分布式任务队列的认识和基本操作
一、简单认识  Celery是由Python开发、简单、灵活、可靠的分布式任务队列,其本质是生产者消费者模型,生产者发送任务到消息队列,消费者负责处理任务。Celery侧重于实时操作,但对调度支持也很好,其每天可以处理数以百万计的任务。它的特点有:简单:熟悉了它的流程后,配置使用简单;高可用
Stella981 Stella981
2年前
Redis 发布订阅模式(7)
列表的局限前面我们说通过队列的rpush和lpop可以实现消息队列(队尾进队头出),但是消费者需要不停地调用lpop查看List中是否有等待处理的消息(比如写一个while循环)。为了减少通信的消耗,可以sleep()一段时间再消费,但是会有两个问题:1、如果生产者生产消息的速度远大于消费者消费消息的速度,List会占用大量的内存。2、
Stella981 Stella981
2年前
RabbitMQ如何高效的消费消息
在上篇介绍了如何简单的发送一个消息队列之后,我们本篇来看下RabbitMQ的另外一种模式,工作队列。什么是工作队列我们上篇文章说的是,一个生产者生产了消息被一个消费者消费了,如下图!(https://usergoldcdn.xitu.io/2020/5/15/1721768c1b303014?w1824&h55
Wesley13 Wesley13
2年前
3.rabbitmq
rabbitmq发布订阅模式模型组成一个消费者Producer,一个交换机Exchange,多个消息队列Queue,多个消费者Consumer一个生产者,多个消费者,每一个消费者都有自己的一个队列,生产者没有将消息直接发送到队列,而是发送到了交换机,每个队列绑定交换机,生产者发送
Wesley13 Wesley13
2年前
Java多线程之线程安全队列Queue
在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列。Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。注:什么叫线程安全?这个首先要明确。
Wesley13 Wesley13
2年前
C++ 多线程编程总结
在开发C程序时,一般在吞吐量、并发、实时性上有较高的要求。设计C程序时,总结起来可以从如下几点提高效率:并发异步缓存下面将我平常工作中遇到一些问题例举一二,其设计思想无非以上三点。1任务队列1.1   以生产者消费者模型设计任务队列      生产者消费者模型是人们非常熟
Stella981 Stella981
2年前
BlockingQueue队列生产者消费者示例
package org.web.controller.queue;import java.util.Random;import java.util.concurrent.BlockingQueue;import java.util.concurrent.TimeUnit;import java.uti
Wesley13 Wesley13
2年前
JAVA线程15
一、阻塞队列1\.概述阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue。阻塞队列是一个指定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止。同样,当队列为空时候,请求队列元素的操作同样会阻塞等待,直到有可用元
Easter79 Easter79
2年前
SpringMVC中配置RabbitMQ
        RabbitMQ是工作在amqp协议(advancedmessagequeueprotocal,高级消息队列协议)上的一个消息中间件。它通过一个生产者消费者模型来处理应用中产生的消息。        除了生产者和消费者,此模型中另外一个重要的概念叫“工作队列”,也称为“任务队列”(TaskQueue),任务队列背后的核心想法是避免
Wesley13 Wesley13
2年前
Java并发 阻塞队列
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加操作支持阻塞地插入和移除方法。支持阻塞插入的方法是指当队列满时会阻塞插入元素的线程,直到队列不满;支持阻塞移除的方法是指当队列为空时获取元素的线程无法继续获取元素直到队列不空。可以发现阻塞队列非常适合消费者和生产者场景下进行使用,生产者生产数据就是向阻塞队列中插入元素,消费者消