34.Java 阻塞队列(阻塞队列架构、阻塞队列分类、阻塞队列核心方法)

一、阻塞队列概述

  • java.util.concurrent 包下的 BlockingQueue 接口很好的解决了多线程中如何高效安全传输数据的问题,可以使用这些高效并且线程安全的队列类快速搭建高质量的多线程程序

  • 阻塞队列通过一个共享的队列,使得数据由队列的一端输入,从另外一端输出,当队列空时,从队列中获取元素的操作将会被阻塞,当队列满时,从队列中添加元素的操作将会被阻塞

  • 试图从空的队列中获取元素的线程将会被阻塞,直到其他线程往空的队列插入新的元素,试图向已满的队列中添加新元素的线程将会被阻塞,直到其他线程从队列中移除一个或多个元素或者完全清空

  • 所谓阻塞,即在某些情况下将线程挂起,一旦条件满足,被挂起的线程会自动被唤起

  • 多线程环境中,通过队列可以很容易实现数据共享,比如经典的生产者和消费者模型,通过队列可以很便利地实现两者之间的数据共享

  • 当队列中没有数据时,消费者端的所有线程都会被阻塞,直到有数据存入队列,当队列中填满数据的情况下,生产者端的所有线程都会被阻塞,直到队列中有空间


二、阻塞队列架构

  • BlockingQueue 接口的超接口有 Collection、Iterable、Queue

  • BlockingQueue 接口的实现类有 ArrayBlockingQueue、DelayQueue、LinkedBlockingDeque、LinkedBlockingQueue、LinkedTransferQueue、PriorityBlockingQueue、SynchronousQueue


三、阻塞队列分类

1、ArrayBlockingQueue 类
  • ArrayBlockingQueue 是由数组结构实现的有界阻塞队列

  • ArrayBlockingQueue 在生产者存放数据和消费者获取数据时都是共用同一个锁对象,无法并行

2、LinkedBlockingQueue 类
  • LinkedBlockingQueue 是由链表结构实现的有界阻塞队列,大小默认值为 Integer.MAX_VALUE

  • LinkedBlockingQueue 对于生产者端和消费者端分别采用了独立的锁来控制数据同步,在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能

3、DelayQueue 类
  • 基于优先级队列实现的延迟无界阻塞队列

  • DelayQueue 中的数据只有当其达到指定的延迟时间,才能够从队列中获取到该数据

  • DelayQueue 是一个没有大小限制的队列,因此往队列中插入数据的操作(生产者)不会被阻塞,只有获取数据的操作(消费者)才会被阻塞

4、PriorityBlockingQueue 类
  • PriorityBlockingQueue 是基于优先级排序实现的无界阻塞队列

  • PriorityBlockingQueue 不会阻塞数据生产者,只会在没有可消费的数据时,阻塞数据的消费者

5、SynchronousQueue 类
  • SynchronousQueue 是无缓冲的等待队列

  • 相对于有缓冲的 BlockingQueue 来说,SynchronousQueue 少了一个中间经销商的环节(缓冲区)

  • SynchronousQueue 是不存储元素的阻塞队列,也即单个元素的队列

  • 声明一个 SynchronousQueue 对象有公平模式和非公平模式两种方式

(1)公平模式
  • SynchronousQueue 使用公平锁,并配合一个先进先出(FIFO)队列来阻塞多余的生产者和消费者,从而体系整体的公平策略
(2)非公平模式
  • SynchronousQueue 使用非公平锁,同时配合一个后进先出(LIFO)队列来管理多余的生产者和消费者

  • 这种模式,如果生产者和消费者的数据处理速度有差距,则很容易出现线程饥饿饥饿的情况,即可能有某些生产者或者是消费者的数据永远都得不到处理

6、LinkedTransferQueue 类
  • LinkedTransferQueue 是基于链表结构实现的无界阻塞队列

  • LinkedTransferQueue 采用一种预占模式,当消费者线程取数据时,如果队列不为空,则直接取走数据,若队列为空,那就生成一个节点数据为 null 的节点入队,然后消费者线程在该节点上等待,之后生产者线程入队时发现有一个节点数据为 null 的节点,生产者线程就不入对了,直接将数据填充到该节点,并唤醒该节点等待的消费者线程,被唤醒的消费者线程取走数据,从调用的方法返回

7、LinkedBlockingDeque 类
  • LinkedBlockingDeque 是基于链表结构组成的双向阻塞队列

  • LinkedBlockingDeque 有两种阻塞情况

(1)插入数据时阻塞
  • 当队列满时会进入阻塞状态,直到队列有空的位置时才可插入数据

  • 插入数据的操作可以通过设置超时时间,超时后返回 false 表示操作失败,也可以不设置超时时间,但是会被一直阻塞,被中断后会抛出 InterruptedException 异常

(2)读取数据时阻塞
  • 当队列空时会进入阻塞状态,直到队列不为空才可读取数据

  • 读取数据的操作同样可以设置超时时间


四、阻塞队列核心方法

  • BlockingQueue 的核心方法可以根据队列已满或为空时的执行情况分为抛出异常组、返回特殊值组、阻塞组、超时组
1、抛出异常组
(1)基本介绍
方法说明
boolean add(Object o)插入数据,成功时返回 true,当队列已满时再插入会抛出 java.lang.IllegalStateException 异常
Object remove()读取数据,成功时返回数据,当队列为空时再读取会抛出 java.util.NoSuchElementException 异常
Object element()检查数据,成功时返回数据,当队列为空时再读取会抛出 java.util.NoSuchElementException 异常
(2)演示
  • add 方法演示
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);System.out.println(blockingQueue.add(1)); // true
System.out.println(blockingQueue.add(2)); // true
System.out.println(blockingQueue.add(3)); // true
System.out.println(blockingQueue.add(4)); // 抛出 java.lang.IllegalStateException 异常
  • remove 方法演示
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);System.out.println(blockingQueue.add(1)); // true
System.out.println(blockingQueue.add(2)); // true
System.out.println(blockingQueue.add(3)); // trueSystem.out.println(blockingQueue.remove()); // 1
System.out.println(blockingQueue.remove()); // 2
System.out.println(blockingQueue.remove()); // 3
System.out.println(blockingQueue.remove()); // 抛出 java.util.NoSuchElementException 异常
  • element 方法演示
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);System.out.println(blockingQueue.add(1)); // true
System.out.println(blockingQueue.add(2)); // true
System.out.println(blockingQueue.add(3)); // trueSystem.out.println(blockingQueue.remove()); // 1
System.out.println(blockingQueue.element()); // 2System.out.println(blockingQueue.remove()); // 2
System.out.println(blockingQueue.element()); // 3System.out.println(blockingQueue.element()); // 抛出 java.util.NoSuchElementException 异常
2、返回特殊值组
(1)基本介绍
方法说明
boolean offer(Object o)插入数据,成功时返回 true,当队列已满时再插入返回 false
Object poll()读取数据,成功时返回数据,当队列为空时再读取返回 null
Object peek()检查数据,成功时返回数据,当队列为空时再读取返回 null
(2)演示
  • offer 方法演示
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);System.out.println(blockingQueue.offer(1)); // true
System.out.println(blockingQueue.offer(2)); // true
System.out.println(blockingQueue.offer(3)); // true
System.out.println(blockingQueue.offer(4)); // false
  • poll 方法演示
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);System.out.println(blockingQueue.offer(1)); // true
System.out.println(blockingQueue.offer(2)); // true
System.out.println(blockingQueue.offer(3)); // trueSystem.out.println(blockingQueue.poll()); // 1
System.out.println(blockingQueue.poll()); // 2
System.out.println(blockingQueue.poll()); // 3
System.out.println(blockingQueue.poll()); // null
  • peek 方法演示
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);System.out.println(blockingQueue.offer(1)); // true
System.out.println(blockingQueue.offer(2)); // true
System.out.println(blockingQueue.offer(3)); // trueSystem.out.println(blockingQueue.poll()); // 1
System.out.println(blockingQueue.peek()); // 2System.out.println(blockingQueue.poll()); // 2
System.out.println(blockingQueue.peek()); // 3System.out.println(blockingQueue.poll()); // 3
System.out.println(blockingQueue.peek()); // null

3、阻塞组
(1)基本介绍
方法说明
void put(Object o)插入数据,当队列已满时再插入会阻塞
Object take()读取数据,当队列为空时再读取会阻塞
(2)演示
  • put 方法演示
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);blockingQueue.put(1);
System.out.println("a"); // ablockingQueue.put(2);
System.out.println("b"); // bblockingQueue.put(3);
System.out.println("c"); // cblockingQueue.put(4); // 阻塞
System.out.println("d"); // 阻塞
  • take 方法
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);blockingQueue.put(1);
blockingQueue.put(2);
blockingQueue.put(3);System.out.println(blockingQueue.take()); // 1
System.out.println(blockingQueue.take()); // 2
System.out.println(blockingQueue.take()); // 3
System.out.println(blockingQueue.take()); // 阻塞
4、超时组
(1)基本介绍
方法说明
boolean offer(Object o, long timeout, TimeUnit unit)插入数据,成功时返回 true,当队列已满时再插入会进入超时等待
超时等待后,能成功插入数据则返回 true,失败则返回 false
Object poll(long timeout, TimeUnit unit)读取数据,成功时返回数据,当队列为空时再读取会进入超时等待
超时等待后,能成功读取数据则返回数据,失败则返回 null
(2)演示
  • offer 方法演示
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);System.out.println(blockingQueue.offer(1, 3L, TimeUnit.SECONDS)); // true
System.out.println(blockingQueue.offer(2, 3L, TimeUnit.SECONDS)); // true
System.out.println(blockingQueue.offer(3, 3L, TimeUnit.SECONDS)); // true
System.out.println(blockingQueue.offer(4, 3L, TimeUnit.SECONDS)); // 超时等待,超时等待后返回 false
  • poll 方法演示
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);System.out.println(blockingQueue.offer(1, 3L, TimeUnit.SECONDS)); // true
System.out.println(blockingQueue.offer(2, 3L, TimeUnit.SECONDS)); // true
System.out.println(blockingQueue.offer(3, 3L, TimeUnit.SECONDS)); // trueSystem.out.println(blockingQueue.poll(3L, TimeUnit.SECONDS)); // 1
System.out.println(blockingQueue.poll(3L, TimeUnit.SECONDS)); // 2
System.out.println(blockingQueue.poll(3L, TimeUnit.SECONDS)); // 3
System.out.println(blockingQueue.poll(3L, TimeUnit.SECONDS)); // 超时等待,超时等待后返回 false

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/24320.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯之日期题

文章目录 1.蓝桥杯必备知识点2. 题型13.需求2 1.蓝桥杯必备知识点 蓝桥杯是一个面向全国高校计算机相关专业学生的学科竞赛,涵盖多个赛道,常见的有软件类(如 C/C 程序设计、Java 软件开发、Python 程序设计)和电子类(…

本地部署大模型: LM Studio、Open WebUI 与 Chatbox 全面对比以及选型指南

1. 工具概述 LM Studio 定位:专注于本地化大模型实验与推理的桌面工具,支持多模型并行、Hugging Face集成及离线运行。 核心功能: 图形化界面直接加载GGUF模型文件,支持NVIDIA/AMD GPU加速。 内置OpenAI兼容API,可搭…

springboot实现多文件上传

springboot实现多文件上传 代码 package com.sh.system.controller;import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PostMap…

最新版IDEA下载安装教程

一、下载IDEA 点击前往官网下载 或者去网盘下载 点击前往百度网盘下载 点击前往夸克网盘下载 进去后点击IDEA 然后点击Download 选择自己电脑对应的系统 点击下载 等待下载即可 二、安装IDEA 下载好后双击应用程序 点击下一步 选择好安装目录后点击下一步 勾选这两项后点击…

vue3学习2

ts定义接口: 引入的时候要加type: 调用: ts创建自定义type类型,引入的时候也要加type: reactive可以直接传泛型: 加?声明不强制: defineProps接收父组件传递的props,其中defineProp…

Proof Beyond Boundaries: Hong Kong zkNight 活动精彩回顾

2 月 19 日,随着夜幕的降临,一场汇聚行业智慧与前瞻视野的高端主题活动 ——Proof Beyond Boundaries: Hong Kong zkNight,在香港铜锣湾 Vpoint 的 6/F 盛大启幕。本次活动由 ZEROBASE 主办,Techub News 承办,吸引了众…

PDF转HTML 超级好用 免费在线转换PDF 完美转换格式

PDF转HTML 超级好用 免费在线转换PDF 完美转换格式,PDF已成为一种广泛使用的文件格式,用于保存和分享文档。然而,PDF文件在某些场景下可能不够灵活,特别是在需要在网页上直接展示其内容时。为了满足这一需求,小白工具推…

星环科技推出DeepSeek全场景解决方案:即开即用、企业级部署、端侧智能三位一体

星环科技(688031.SH)正式发布DeepSeek全场景解决方案,全面覆盖个人用户、企业客户及行业场景需求,为用户提供从个人到企业、从云端到本地的全方位AI应用支持,为不同需求的用户提供了灵活、高效且安全的AI解决方案。 省…

全价值链数字化转型:以美的集团为例,探索开源AI大模型与S2B2C商城小程序源码的融合应用

摘要:在数字经济时代背景下,企业面临着前所未有的竞争压力与市场变革。全价值链的数字化转型,作为提升企业核心竞争力的关键策略,正逐步成为行业共识。美的集团,作为家电行业的领军企业,其基于数字化的全价…

Hi3516CV610开发板ISP调试之——图像ISP在线调试 环境搭建教程

本文讲解Hi3516CV610开发板如何实时在线调试图像ISP参数 首先烧录好资料包中的出厂固件(默认出厂已烧录好),接好网线、usb转串口线、电源,进入开发板系统 打开odm查看实时视频 解压打开资料包中的PQTools_V1.x.xx.zip并找到PQTool…

isaac gym使用记录

一、使用测试 这里跑的是isaac gym官方的强化学习环境代码isaacgymenvs 下载链接:https://zhuanlan.zhihu.com/p/671309384 1、 运行命令和效果 训练命令 python train.py taskCartpole #headlessTrue运行倒立摆任务,运行一会就可以收敛。headless设置…

国科大——数据挖掘(0812课程)——课后作业

前沿: 此文章记录了2024年度秋季学期数据挖掘课程的三次课后作业,答案仅供参考。 第一次作业 1 假定数据仓库中包含4个维:date, product, vendor, location;和两个度量:sales_volume和sales_cost。 1)画…

基于SpringBoot的“古城景区管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“古城景区管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统整体功能图 系统首页界面 系统注册界面 景…

HarmonyOS Design 介绍

HarmonyOS Design 介绍 文章目录 HarmonyOS Design 介绍一、HarmonyOS Design 是什么?1. 设计系统(Design System)2. UI 框架的支持3. 设计工具和资源4. 开发指南5. 与其他设计系统的对比总结 二、HarmonyOS Design 特点 | 应用场景1. Harmon…

面试题——简述Vue 3的服务器端渲染(SSR)是如何工作的?

面试题——简述Vue3的服务器端渲染(SSR)是如何工作的? 服务器端渲染(SSR)已经成为了一个热门话题。Vue 3,作为一款流行的前端框架,也提供了强大的SSR支持。那么,Vue 3的SSR究竟是如何…

汽车零部件工厂如何通过ESD监控系统闸机提升产品质量

在汽车零部件工厂的生产过程中,静电带来的危害不容小觑。从精密的电子元件到复杂的机械部件,静电都可能成为影响产品质量的 “隐形杀手”。而 ESD 监控系统闸机的出现,为汽车零部件工厂解决静电问题、提升产品质量提供了关键的技术支持。 一、…

AWQ和GPTQ量化的区别

一、前言 本地化部署deepseek时发现,如果是量化版的deepseek,会节约很多的内容,然后一般有两种量化技术,那么这两种量化技术有什么区别呢? 二、量化技术对比 在模型量化领域,AWQ 和 GPTQ 是两种不同的量…

IDEA关闭SpringBoot程序后仍然占用端口的排查与解决

IDEA关闭SpringBoot程序后仍然占用端口的排查与解决 问题描述 在使用 IntelliJ IDEA 开发 Spring Boot 应用时,有时即使关闭了应用,程序仍然占用端口(例如:4001 端口)。这会导致重新启动应用时出现端口被占用的错误&a…

数字IC后端设计实现OCC(On-chip Clock Controller)电路介绍及时钟树综合案例

数字IC后端时钟树综合专题(OCC电路案例分享) 复杂时钟设计时钟树综合(clock tree synthesis)常见20个典型案例 1、什么是OCC? 片上时钟控制器(On-chip Clock Controllers ,OCC),也称为扫描时钟控制器(Scan Clock Con…

IP离线库助力破解网络反诈难题

毫秒级响应识别异常访问 IP离线库集成全球全量IP地址的详细信息,包括地理地址查询、运营商、经纬度、代理识别等多种维度数据。例如: 当用户账号频繁从北京、越南等多地IP登录时,系统将自动触发风险预警; 检测到访问IP为已知机…