07_阻塞队列(BlockingQueue)

2023-05-16

目录

1. 什么是BlockingQueue

2. 认识BlockingQueue

3. 代码演示


栈与队列概念

栈(Stack):先进后出,后进先出

队列:先进先出

1. 什么是BlockingQueue

在多线程领域:所谓阻塞,在某些情况下会挂起线程(即阻塞),一旦条件满足,被挂起的线程又会自动被唤起。

BlockingQueue即阻塞队列,是java.util.concurrent下的一个接口,因此不难理解,BlockingQueue是为了解决多线程中数据高效安全传输而提出的。从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种:

  1. 当队列满了的时候进行入队列操作

  2. 当队列空了的时候进行出队列操作

因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空队列进行出队列操作时,它将会被阻塞,除非有另一个线程进行了入队列操作。

阻塞队列主要用在生产者/消费者的场景,下面这幅图展示了一个线程生产、一个线程消费的场景:

为什么需要BlockingQueue?

好处是我们不需要关心什么时候需要阻塞线程,什么时候需要唤醒线程,因为这一切BlockingQueue都给你一手包办了。在concurrent包发布以前,在多线程环境下,我们每个程序员都必须去自己控制这些细节,尤其还要兼顾效率和线程安全,而这会给我们的程序带来不小的复杂度。

2. 认识BlockingQueue

java.util.concurrent 包里的 BlockingQueue是一个接口,继承Queue接口,Queue接口继承 Collection。

BlockingQueue接口主要有以下7个实现类:

  1. ArrayBlockingQueue:由数组结构组成的有界阻塞队列。

  2. LinkedBlockingQueue:由链表结构组成的有界(但大小默认值为integer.MAX_VALUE)阻塞队列。

  3. PriorityBlockingQueue:支持优先级排序的无界阻塞队列。

  4. DelayQueue:使用优先级队列实现的延迟无界阻塞队列。

  5. SynchronousQueue:不存储元素的阻塞队列,也即单个元素的队列。

  6. LinkedTransferQueue:由链表组成的无界阻塞队列。

  7. LinkedBlockingDeque:由链表组成的双向阻塞队列。

BlockingQueue接口有以下几个方法:它的方法可以分成以下4类:

抛出异常特殊值阻塞超时
插入add(e)offer(e)put(e)offer(e, time, unit)
移除remove()poll()take()poll(time, unit)
检查element()peek()不可用不可用

① 抛出异常

add正常执行返回true,element(不删除)和remove返回阻塞队列中的第一个元素​ 当阻塞队列满时,再往队列里add插入元素会抛IllegalStateException:Queue full​ 当阻塞队列空时,再往队列里remove移除元素会抛NoSuchElementException​ 当阻塞队列空时,再调用element检查元素会抛出NoSuchElementException。

② 特定值

插入方法,成功ture失败false 移除方法,成功返回出队列的元素,队列里没有就返回null 检查方法,成功返回队列中的元素,没有返回null。

③ 一直阻塞

如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行。​ 当阻塞队列满时,再往队列里put元素,队列会一直阻塞生产者线程直到put数据or响应中断退出​ 当阻塞队列空时,再从队列里take元素,队列会一直阻塞消费者线程直到队列可用。

④ 超时退出

如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行,但等待时间不会超过给定值。​ 返回一个特定值以告知该操作是否成功(典型的是 true / false)。

3. 代码演示

public class BlockingQueueDemo {

    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
        // 第一组方法:add remove element
//        System.out.println(queue.add("a"));
//        System.out.println(queue.add("b"));
//        System.out.println(queue.add("c"));
//        // System.out.println(queue.add("d"));
//        // System.out.println(queue.element());
//        System.out.println(queue.remove());
//        System.out.println(queue.remove());
//        System.out.println(queue.remove());
//        //System.out.println(queue.remove());
//        //System.out.println(queue.element());
        // 第二组:offer poll peek
//        System.out.println(queue.offer("a"));
//        System.out.println(queue.offer("b"));
//        System.out.println(queue.offer("c"));
//        System.out.println(queue.offer("d"));
//        System.out.println(queue.peek());
//        System.out.println(queue.poll());
//        System.out.println(queue.poll());
//        System.out.println(queue.poll());
//        System.out.println(queue.poll());
//        System.out.println(queue.peek());
        // 第三组:put take
//        queue.put("a");
//        queue.put("b");
//        queue.put("c");
//        System.out.println(queue.take());
//        queue.put("d");
//        System.out.println(queue.take());
//        System.out.println(queue.take());
//        System.out.println(queue.take());
        // 第四组:offer poll
        System.out.println(queue.offer("a"));
        System.out.println(queue.offer("b"));
        System.out.println(queue.offer("c"));
        System.out.println(queue.offer("d", 5, TimeUnit.SECONDS));
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

07_阻塞队列(BlockingQueue) 的相关文章

  • BlockingQueue深入分析

    1 BlockingQueue 定义的常用方法如下 抛出异常特殊值阻塞超时插入add e offer e put e offer e time unit 移除remove poll take poll time unit 检查element
  • BlockingQueue

    BlockingQueue 一 阻塞队列基本方法介绍 谈到线程池 xff0c 不得不谈到生产者 消费者模式 xff0c 谈到生产者 消费者 xff0c 就不得不谈到对应的数据结构 xff0c 谈到对应的数据结构不得不言 BlockingQu
  • 阻塞队列)详解

    一 前言 在新增的Concurrent包中 xff0c BlockingQueue很好的解决了多线程中 xff0c 如何高效安全 传输 数据的问题 通过这些高效并且线程安全的队列类 xff0c 为我们快速搭建高质量的多线程程序带来极大的便利
  • 阻塞队列-BlockingQueue

    对于Queue而言 xff0c BlockingQueue是主要的线程安全的版本 xff0c 具有阻塞功能 xff0c 可以允许添加 删除元素被阻塞 xff0c 直到成功为止 xff0c blockingqueue相对于Queue而言增加了
  • BlockingQueue深入分析

    1 BlockingQueue 定义的常用方法如下 抛出异常特殊值阻塞超时插入add e offer e put e offer e time unit 移除remove poll take poll time unit 检查element
  • Java 阻塞队列--BlockingQueue

    1 什么是阻塞队列 xff1f 阻塞队列 xff08 BlockingQueue xff09 是一个支持两个附加操作的队列 这两个附加的操作是 xff1a 在队列为空时 xff0c 获取元素的线程会等待队列变为非空 当队列满时 xff0c
  • ArrayBlockingQueue

    在java多线程操作中 BlockingQueue
  • Java基础学习之并发篇:手写阻塞队列ArrayBlockingQueue

    学习目标 我们都知道在并发编程中 阻塞队列在多线程中的场景特别有用 比如在生产和消费者模型中 生产者生产数据到队列 队列满时需要阻塞线程 停止生产 消费者消费队列 对队列为空时阻塞线程停止消费 在Java中有提供不同场景的阻塞队列 那么接下
  • Feign 使用 @SpringQueryMap 来解决多参数传递问题

    本文目录 1 Feign传递一个bean对象参数 2 Feign传递一个bean对象参数 多个基本类型参数 3 Feign传递多个基本类型参数 4 Feign传递多个bean对象参数 在实际项目开发过程中 我们使用 Feign 实现了服务与
  • 如何并行等待多个阻塞队列?

    我有两个独立的阻塞队列 客户端通常使用第一个或第二个阻塞队列来检索要处理的元素 在某些情况下 客户端对两个阻塞队列中的元素感兴趣 无论哪个队列首先提供数据 客户端如何并行等待两个队列 您可以尝试使用poll某种循环中的方法 仅在轮询另一个队
  • 有没有办法保存最大 1 MB 的“消息”集合并将结果写入 JSON/CSV 文件

    我有一个阻塞队列 它不断通过某些应用程序获取消息 现在在 asp net 应用程序中 我尝试使用该队列并将输出写入 CSV JSON 文件 在这里 我想保存最多 1MB 的消息 这些消息从阻塞队列接收 然后将其写出 现在再次保存 1MB 的
  • Java中可以使用Semaphore实现阻塞队列吗?

    我想知道是否可以使用Semaphore来实现阻塞队列 在下面的代码中 我使用一个信号量来保护关键部分 并使用另外两个信号量对象来跟踪空槽和已填充对象的数量 public class BlockingQueue private List qu
  • Mediacodec,解码来自服务器的字节数据包并将其渲染在表面上

    我对 MediaCode 有一些问题 我有 3 个组件 解码器 下载器和渲染器 又简单FragmentStreamVideo初始化 SurfaceView 和 Downloader 其他组件 例如渲染器和解码器 在 SurfaceView
  • 生产者消费者 - ExecutorService 和 ArrayBlockingQueue

    我想知道我对使用 ExecutorService 和 ArrayBlockingQueue 的生产者消费者设计的理解是否正确 我知道有不同的方法来实现这个设计 但我想 最终 这取决于问题本身 我必须面对的问题是 我有一个制作人 他从一个大文
  • 如何立即释放在BlockingQueue上等待的线程

    考虑一个BlockingQueue和一些等待的线程poll long TimeUnit 也可能在take 现在队列是空的 需要通知等待线程它们可以停止等待 预期的行为是null退回或申报的InterruptedException throw
  • 多生产者多消费者多线程Java

    我正在尝试生产者 消费者问题的多个生产者 多个消费者用例 我使用 BlockingQueue 在多个生产者 消费者之间共享公共队列 下面是我的代码 Producer import java util concurrent BlockingQ
  • 异步通知 BlockingQueue 有可用项目

    我需要一个Object当某些情况时得到异步通知BlockingQueue有一件物品要赠送 我在 Javadoc 和网络上搜索了一个预制的解决方案 然后我最终得到了我的一个 也许是幼稚的 解决方案 如下 interface QueueWait
  • 为什么 LogWriter 中的竞争条件会导致生产者阻塞? 【并发实践】

    首先 为了防止那些不喜欢读到我已读完的人将问题标记为重复生产者 消费者日志服务以不可靠的方式关闭 https stackoverflow com questions 31626772 producer consumer logging se
  • 如何阻塞直到BlockingQueue为空?

    我正在寻找一种方法来阻止直到BlockingQueue是空的 我知道 在多线程环境下 只要有生产者将物品放入BlockingQueue 可能会出现队列变空 几纳秒后又充满项目的情况 但是 如果只有one生产者 那么它可能希望在停止将项目放入
  • 在java中实现你自己的阻塞队列

    我知道这个问题之前已经被问过并回答过很多次了 但我只是无法根据互联网上找到的示例找出窍门 例如this http tutorials jenkov com java concurrency blocking queues html or t

随机推荐

  • Vue3中axios的使用与封装

    文章目录 一 安装axios二 配置与封装三 引入与使用 一 安装axios span class token function npm span i axios s 二 配置与封装 src aixos request js http js
  • MySQL常见七种通用的Join查询练习题

    准备数据库表 t dept 和 t emp CREATE TABLE 96 t dept 96 96 id 96 int NOT NULL AUTO INCREMENT 96 deptName 96 varchar 30 DEFAULT N
  • MySQL索引分类

    主键索引 xff1a 设定为主键后数据库会自动建立索引 xff0c innodb为聚簇索引 单值索引 xff1a 即一个索引只包含单个列 xff0c 一个表可以有多个单列索引 唯一索引 xff1a 索引列的值必须唯一 xff0c 但允许有空
  • Docker 部署 MySQL 一主多从

    主从复制的原理 xff1a 1 主库 xff1a 创建一个有权访问binlog日志的从库账号 xff0c 配置需要主从复制的库 有写操作时 xff0c 可以将写操作或者写操作之后的数据记录到日志文件中 binlog 通过一个线程通知需要同步
  • Java笔记(8)——重载(Overload)与重写(Override)的区别

    1 重写 xff08 Override xff09 重写是子类对允许访问的父类的方法进行重新编写的过程 xff0c 方法名 返回值和参数列表不能变 xff0c 方法中的内容可以变化 特点就是 xff1a 子类可以根据自己的需要对父类的方法进
  • ShardingSphere介绍

    官网 xff1a https shardingsphere apache org index zh html 文档 xff1a https shardingsphere apache org document 5 1 1 cn overvi
  • ShardingSphere-JDBC读写分离

    基于之前搭建的mysql主从读写分离使用ShardingSphere JDBC实现读写分离 参考文章 xff1a Docker 部署 MySQL 一主多从 书启秋枫的博客 CSDN博客 CREATE DATABASE mydb2 USE m
  • ShardingSphere-JDBC垂直分片

    什么是数据分片 xff1f 简单来说 xff0c 就是指通过某种特定的条件 xff0c 将我们存放在同一个数据库中的数据分散存放到多个数据库 xff08 主机 xff09 上面 xff0c 以达到分散单台设备负载的效果 数据的切分 xff0
  • ShardingSphere-JDBC水平分片

    项目中可以使用ShardingSphere JDBC将数据存到不同库的表中 一 准备服务器 服务器规划 xff1a 使用docker方式创建如下容器 主服务器 xff1a 容器名server order0 xff0c 端口3310从服务器
  • ShardingSphere-JDBC绑定表

    一 什么是绑定表 指分片规则一致的一组分片表 使用绑定表进行多表关联查询时 xff0c 必须使用分片键进行关联 xff0c 否则会出现笛卡尔积关联或跨库关联 xff0c 从而影响查询效率 例如 xff1a t order 表和 t orde
  • ShardingSphere-JDBC广播表

    一 什么是广播表 指所有的分片数据源中都存在的表 xff0c 表结构及其数据在每个数据库中均完全一致 适用于数据量不大且需要与海量数据的表进行关联查询的场景 xff0c 例如 xff1a 字典表 广播具有以下特性 xff1a xff08 1
  • 01_JUC概述

    1 JUC是什么 xff1f 在 Java 5 0 提供了 java util concurrent 简称JUC 包 xff0c 在此包中增加了在并发编程中很常用的工具类 此包包括了几个小的 已标准化的可扩展框架 xff0c 并提供一些功能
  • 02_Lock锁

    首先看一下JUC的重磅武器 锁 xff08 Lock xff09 相比同步锁 xff0c JUC包中的Lock锁的功能更加强大 xff0c 它提供了各种各样的锁 xff08 公平锁 xff0c 非公平锁 xff0c 共享锁 xff0c 独占
  • 03_线程间通信

    面试题 xff1a 两个线程打印 两个线程 xff0c 一个线程打印1 52 xff0c 另一个打印字母A Z打印顺序为12A34B 5152Z xff0c 要求用线程间通信 public class Demo01 public stati
  • 04_并发容器类

    1 重现线程不安全 xff1a List 首先以List作为演示对象 xff0c 创建多个线程对List接口的常用实现类ArrayList进行add操作 public class NotSafeDemo public static void
  • Java笔记(10)——异常处理

    1 Java异常 Java运行时发生异常可以分为两类 xff1a Error xff1a JVM系统内部错误 资源耗尽等问题产生的异常 Exception xff1a 编程错误或偶然的外在因素导致的 2 常见的异常 2 1 RuntimeE
  • mariadb 数据库连接使用

    今天测试了使用mariadb的使用 xff0c 我使用的springboot 43 mariadb 来操作数据库 xff0c 和以前的代码基本一样 xff0c 就数据变成了mariadb xff0c 驱动还是使用mysql的 pom 文件如
  • 05_JUC强大的辅助类

    JUC的多线程辅助类非常多 xff0c 这里我们介绍三个 xff1a CountDownLatch xff08 倒计数器 xff09 CyclicBarrier xff08 循环栅栏 xff09 Semaphore xff08 信号量 xf
  • 06_Callable接口

    Thread 类 Runnable 接口使得多线程编程简单直接 但Thread类和Runnable接口都不允许声明检查型异常 xff0c 也不能定义返回值 没有返回值这点稍微有点麻烦 不能声明抛出检查型异常则更麻烦一些 public voi
  • 07_阻塞队列(BlockingQueue)

    目录 1 什么是BlockingQueue 2 认识BlockingQueue 3 代码演示 栈与队列概念 栈 Stack xff1a 先进后出 xff0c 后进先出 队列 xff1a 先进先出 1 什么是BlockingQueue 在多线