当前位置: 首页 > news >正文

Java基于数组的阻塞队列实现详解

在多线程编程中,阻塞队列是一种非常有用的工具,它可以在生产者和消费者之间提供一个缓冲区,使得生产者可以往队列中添加数据,而消费者可以从队列中取出数据。当队列满时,生产者会被阻塞直到有空间可用;当队列空时,消费者会被阻塞直到有数据可用。本文将详细分析一个基于数组实现的阻塞队列代码。

代码结构概述

我们先来浏览一下整个代码的结构:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class ArrBlockQueue<E> {// 成员变量private Object[] arr;private int size = 0;private int head = 0;  // 存数据位置private int last = 0;  // 取数位置private ReentrantLock lock = new ReentrantLock();private Condition notEmpty = lock.newCondition();private Condition notFull = lock.newCondition();// 构造函数public ArrBlockQueue(int len) {arr = new Object[len];}// 添加数据方法public void put(E e) throws InterruptedException {lock.lock();try {while (size == arr.length) {notFull.await();}System.out.println("put 添加数据 " + e);arr[head] = e;head = (head + 1) % arr.length;size++;notEmpty.signal();} finally {lock.unlock();}}// 取出数据方法(未完成)public E take() throws InterruptedException {}// 获取队列大小方法public int size() {lock.lock();try {return size;} finally {lock.unlock();}}// 主方法(测试用)public static void main(String[] args) {// 测试代码}
}

关键组件解析

1. 同步控制部分

private ReentrantLock lock = new ReentrantLock();
private Condition notEmpty = lock.newCondition();
private Condition notFull = lock.newCondition();

这里使用了ReentrantLockCondition来实现同步控制:

  • ReentrantLock:这是一个可重入的互斥锁,它可以替代synchronized关键字提供更灵活的锁定机制。在这里,它用于确保对共享资源的独占访问。

  • Condition:这是ReentrantLock的一个条件变量接口,用于实现复杂的等待/通知机制。在这里,我们创建了两个条件变量:

    • notEmpty:用于通知消费者队列已非空,可以取数据了。
    • notFull:用于通知生产者队列已非满,可以添加数据了。

2. 数据存储部分

private Object[] arr;
private int size = 0;
private int head = 0;  // 存数据位置
private int last = 0;  // 取数位置

这是阻塞队列的核心数据结构:

  • arr:一个对象数组,用于存储队列中的元素。
  • size:当前队列中的元素数量。
  • head:指向队列头部(下一个要添加元素的位置)。
  • last:指向队列尾部(下一个要取出元素的位置)。

3. 添加数据方法

public void put(E e) throws InterruptedException {lock.lock();try {while (size == arr.length) {notFull.await();}System.out.println("put 添加数据 " + e);arr[head] = e;head = (head + 1) % arr.length;size++;notEmpty.signal();} finally {lock.unlock();}
}

这是生产者线程调用的方法:

  • lock.lock():获取锁,确保线程安全。

  • while (size == arr.length):检查队列是否已满。如果队列满了,调用notFull.await()使当前线程进入等待状态,直到队列有空间可用。

  • 添加数据到arr数组的head位置,更新head指针,并增加size计数。

  • notEmpty.signal():通知可能正在等待队列非空的消费者线程,队列已经可以取出数据了。

  • lock.unlock():释放锁。

代码运行示例

main方法中,创建了一个长度为5的阻塞队列实例:

ArrBlockQueue<Integer> block = new ArrBlockQueue<>(5);

启动两个线程:

  1. 一个生产者线程,循环添加10个元素到队列中:
new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + ": put 线程启动!");for (int i = 0; i < 10; i++) {try {block.put(i);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}).start();
  1. 一个消费者线程,循环从队列中取出10个元素:
new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + ": take 线程启动!");for (int i = 0; i < 10; i++) {try {Thread.sleep(500);System.out.println(block.take());} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}).start();

总结

这个基于数组的阻塞队列实现展示了如何使用ReentrantLockCondition来实现复杂的等待/通知机制。它为生产者和消费者模式提供了一个线程安全的解决方案,确保了数据的一致性和线程间的高效协作。理解这种实现方式有助于我们更好地掌握Java并发编程的核心概念。

相关文章:

Java基于数组的阻塞队列实现详解

在多线程编程中&#xff0c;阻塞队列是一种非常有用的工具&#xff0c;它可以在生产者和消费者之间提供一个缓冲区&#xff0c;使得生产者可以往队列中添加数据&#xff0c;而消费者可以从队列中取出数据。当队列满时&#xff0c;生产者会被阻塞直到有空间可用&#xff1b;当队…...

ngx_http_random_index_module 模块概述

一、使用场景 随机内容分发 当同一目录下存放多份等价内容&#xff08;如多张轮播图、不同版本静态页面等&#xff09;时&#xff0c;可通过随机索引实现负载均衡或流量分散。A/B 测试 通过目录请求自动随机分配用户到不同测试组&#xff0c;无需后端逻辑参与。动态“首页”选…...

你引入的lodash充分利用了吗?

#开发中&#xff0c;发现自己只有cloneDeep的时候才想起来用这个库的便利&#xff0c;搜索了项目内代码&#xff0c;发现大家基本也是这样&#xff0c;其实我们错过了很多好东西# cloneDeep 深拷贝 var objects [{ a: 1 }, { b: 2 }];var deep _.cloneDeep(objects); conso…...

Python爬虫基础

本篇内容中&#xff0c;我们主要分享一些爬虫的前置知识&#xff0c;主要知识点有&#xff1a; 爬虫的概念和作用爬虫的流程【重要】http相关的复习 http和https概念和区别浏览器访问一个网址的过程爬虫中常用的请求头、响应头常见的响应状态码 浏览器自带开发者工具的使用 爬…...

飞帆控件:on_post_get 接口配置

在网页中写一个接口是很基础的要求。 今天我们介绍一个工具&#xff0c;不用写代码&#xff0c;配置即可。 先上链接&#xff1a; on_post_gethttps://fvi.cn/798来看看控件的配置&#xff1a; 使用这个控件&#xff0c;在网页中写 post/get 接口可以告别代码。或许能做到初…...

C++笔试题(金山科技新未来训练营):

题目分布&#xff1a; 17道单选&#xff08;每题3分&#xff09;3道多选题&#xff08;全对3分&#xff0c;部分对1分&#xff09;2道编程题&#xff08;每一道20分&#xff09;。 不过题目太多&#xff0c;就记得一部分了&#xff1a; 单选题&#xff1a; static变量的初始…...

Selenium-Java版(css表达式)

css表达式 前言 根据 tag名、id、class 选择元素 tag名 #id .class 选择子元素和后代元素 定义 语法 根据属性选择 验证CSS Selector 组选择 按次序选择子节点 父元素的第n个子节点 父元素的倒数第n个子节点 父元素的第几个某类型的子节点 父元素的…...

19. 结合Selenium和YAML对页面实例化PO对象改造

19. 结合Selenium和YAML对页面实例化PO对象改造 一、架构升级核心思路 1.1 改造核心目标 # 原始PO模式&#xff1a;显式定义元素定位 username (id, ctl00_MainContent_username)# 改造后PO模式&#xff1a;动态属性访问 self.username.send_keys(Tester) # 自动触发元素定…...

MySQL——5、基本查询

表的增删改查 1、Create1.1、单行数据全列插入1.2、多行数据指定列插入1.3、插入否则更新1.4、替换 2、Retrieve2.1、select列2.2、where条件2.3、结果排序2.4、筛选分页结果 3、Update4、Delete4.1、删除数据4.2、截断表 5、插入查询结果6、聚合函数7、group by子句的使用8、实…...

ngx_http_referer_module 模块概述

一、使用场景 防盗链 仅允许本站或特定域名的页面直接引用图片、视频等资源&#xff0c;拒绝第三方网站直接嵌入。流量控制 阻止来自社交媒体、搜索引擎或未知来源的大量自动化抓取。安全审计 简易记录并过滤可疑 Referer&#xff0c;以减少非法请求。 注意 Referer 头可被伪造…...

Go语言--语法基础5--基本数据类型--类型转换

Go 编程语言中 if 条件语句的语法如下&#xff1a; 1、基本形式 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } If 在布尔表达式为 true 时&#xff0c;其后紧跟的语句块执行&#xff0c;如果为 false 则 不执行。 package main import "fmt" …...

用golang实现二叉搜索树(BST)

目录 一、概念、性质二、二叉搜索树的实现1. 结构2. 查找3. 插入4. 删除5. 中序遍历 中序前驱/后继结点 一、概念、性质 二叉搜索树&#xff08;Binary Search Tree&#xff09;&#xff0c;简写BST&#xff0c;又称为二叉查找树 它满足&#xff1a; 空树是一颗二叉搜索树对…...

基于FPGA的电子万年历系统开发,包含各模块testbench

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于FPGA的电子万年历系统开发,包含各模块testbench。主要包含以下核心模块&#xff1a; 时钟控制模块&#xff1a;提供系统基准时钟和计时功能。 日历计算模块&#xff1a…...

上位机知识篇---Web

文章目录 前言 前言 本文简单介绍了Web。...

2025 ISCC 练武赛Pwn-wp(含附件)

前言 去年个人赛报名了忘记打了(笑), 所以这应该算是我第一次参加ISCC, 体验也是非常非常非常非常的cha(第四声)!!! 主办方也是非常幽默&#xff0c;pwn和web都是公用容器&#xff0c;那web最后都被当成玩具玩坏了 下面是这次练武题的pwn所有附件 通过网盘分享的文件&#xf…...

LeetCode Hot100刷题——除自身以外数组的乘积

238. 除自身以外数组的乘积 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&a…...

IDEA - Windows IDEA 代码块展开与折叠(基础折叠操作、高级折叠操作)

一、基础折叠操作 折叠当前代码块&#xff1a;Ctrl - # 操作方式按下 【Ctrl】 键&#xff0c;再按下 【-】 键展开当前代码块&#xff1a;Ctrl # 操作方式按下 【Ctrl】 键&#xff0c;再按下 【】 键折叠所有代码块&#xff1a;Ctrl Shift - # 操作方式按下 【Ctrl】…...

javaSE.Map

Map存储映射关系。键值对。key-value 左边值映射着右边的值&#xff0c;左边相当于钥匙&#xff0c;开到右边的门获取得到信息。 get&#x1f447;put 是否存在该key&#x1f447;containsKey() map.values&#x1f447; entrySet&#x1f447; entrySet()获取map中所有的键…...

Python Requests库完全指南:从入门到精通

引言 在Python的生态系统中&#xff0c;requests库以其简洁优雅的API设计和强大的功能&#xff0c;成为HTTP请求处理领域的标杆工具。无论是数据爬虫开发、API接口调用&#xff0c;还是自动化测试场景&#xff0c;requests都能将复杂的网络交互简化为几行可读性极高的代码。相…...

1.QPushBotton 以及 对象树

目录 1. 创建第一个Qt程序 1.1 初始化设置 ​&#x1f350; 选择存储位置 &#x1f34a; Kit &#x1f34b; 类信息 &#x1f34c; 项目管理 1.2 代码 &#x1f349; main.cpp &#x1f347;widget.h &#x1f353; widget.cpp 1.3 .pro文件 &#x1f348; 常见模块…...

GO语言语法---For循环、break、continue

文章目录 1. 基本for循环&#xff08;类似其他语言的while&#xff09;2. 经典for循环&#xff08;初始化;条件;后续操作&#xff09;3. 无限循环4. 使用break和continue5 . 带标签的循环&#xff08;可用于break/continue指定循环&#xff09;1、break带标签2、continue带标签…...

网络编程-select(二)

一、I/O多路复用 1、为什么要多路复用 之前开启多线程能实时接收数据&#xff0c;并且也不是一次性连接服务。但毕竟是一请求一连接&#xff0c;每有一个客户端向服务端发起请求&#xff0c;就会创建一个线程&#xff0c;当请求达到上千上万&#xff0c;就会创建上千上万的线…...

2025年PMP 学习十九 第12章 项目采购管理

2025年PMP 学习十九 第12章 项目采购管理 序号过程过程组1规划采购管理规划2实施采购执行3控制采购监控4合同管理- 文章目录 2025年PMP 学习十九 第12章 项目采购管理12 项目采购管理建立战略合作伙伴关系的意义&#xff1a;细化采购步骤 12.1 规划采购管理1. **定义与作用**2…...

10.11 LangGraph多角色Agent开发实战:生产级AI系统架构与性能优化全解析

LangGraph 项目:High-level API for Multi-actor Agents 关键词:LangGraph 多角色 Agent, 状态管理, 持久化机制, 工作流编排, 生产级 AI 系统 1. LangGraph 设计哲学与架构演进 LangGraph 是 LangChain 生态中首个面向 多角色协作 Agent 的高阶 API 框架,其核心设计思想可…...

计算机网络概要

⽹络相关基础知识 协议 两设备之间使⽤光电信号传输信息数据 要想传递不同信息 那么⼆者ᳵ就需要约定好的数据格式 层 封装 继承 多态是计算机的性质 它们⽀持了软硬件分层的实现 同层协议可以ᳵ接通信 同层协议ᳵ不直接通信 是各⾃调⽤下层提供的结构能⼒完成通信 分层…...

Visual Studio已更新为17.14+集成deepseek实现高效编程

01 Visual Studio 2022 v17.14。 此更新侧重于全面提供出色的开发人员体验&#xff0c;侧重于稳定性和安全性以及 AI 改进。 02 GPT-4o代码完成模式 我们非常高兴地宣布&#xff0c;新的 GPT-4o Copilot 代码完成模型现已在 Visual Studio 17.14 中为 GitHub Copilot 用户…...

axios的基本使用

1. Axios概述 Axios 是一个基于 Promise 的 HTTP 客户端库&#xff0c;专为浏览器和 Node.js 设计&#xff0c;用来发送AJAX请求。可以通过npm install -g axios安装axios库。Axios有以下特征&#xff1a; 跨平台兼容性&#xff1a;同一套代码可运行于浏览器和 Node.js。在浏…...

【第三十六周】LoRA 微调方法

LoRA 摘要Abstract文章信息引言方法LoRA的原理LoRA在Transformer中的应用补充其他细节 实验与分析LoRA的使用论文实验结果分析 总结 摘要 本篇博客介绍了LoRA&#xff08;Low-Rank Adaptation&#xff09;&#xff0c;这是一种面向大规模预训练语言模型的参数高效微调方法&…...

fcQCA模糊集定性比较分析法-学习笔记

模糊集定性比较分析&#xff08;fsQCA&#xff0c;Fuzzy-set Qualitative Comparative Analysis&#xff09; 是一种结合了定性和定量元素的研究方法&#xff0c;用于分析中小样本数据中的复杂因果关系。 1. 理解基础概念 QCA的核心思想&#xff1a; 基于集合论和布尔代数&a…...

基于WebRTC的实时语音对话系统:从语音识别到AI回复

基于WebRTC的实时语音对话系统&#xff1a;从语音识别到AI回复 在当今数字化时代&#xff0c;实时语音交互已成为人机界面的重要组成部分。本文将深入探讨一个基于WebRTC技术的实时语音对话系统&#xff0c;该系统集成了语音识别(ASR)、大语言模型(LLM)和语音合成(TTS)技术&am…...

Text2SQL:自助式数据报表开发---0517

Text2SQL技术 早期阶段&#xff1a;依赖于人工编写的规则模板来匹配自然语言和SQL语句之间的对应关系 机器学习阶段&#xff1a;采用序列到序列模型等机器学习方法来学习自然语言与SQL之间的关系 LLM阶段&#xff1a;借助LLM强大的语言理解和代码生成能力&#xff0c;利用提示…...

关于 Web 漏洞原理与利用:1. SQL 注入(SQLi)

一、原理&#xff1a; 拼接 SQL 语句导致注入 SQL 注入的根本原因是&#xff1a;开发者将用户的输入和 SQL 语句直接拼接在一起&#xff0c;没有任何过滤或校验&#xff0c;最终被数据库“当作语句”执行了。 这就像是我们给数据库写了一封信&#xff0c;结果攻击者在我们的…...

【NLP 75、如何通过API调用智谱大模型】

事事忘记&#xff0c;事事等待&#xff0c;事事自愈 —— 25.5.18 一、调用智谱大模型 zhipuai.model_api.invoke()&#xff1a;调用智谱 AI 的大模型&#xff08;如 ChatGLM&#xff09;进行文本生成或推理&#xff0c;支持同步请求。 参数列表 参数名类型是否必需默认值说…...

【RabbitMQ】 RabbitMQ高级特性(二)

文章目录 一、重试机制1.1、重试配置1.2、配置交换机&队列1.3、发送消息1.4、消费消息1.5、运行程序1.6、 手动确认 二、TTL2.1、设置消息的TTL2.2、设置队列的TTL2.3、两者区别 三 、死信队列6.1 死信的概念3.2 代码示例3.2.1、声明队列和交换机3.2.2、正常队列绑定死信交…...

EMQX开源版安装指南:Linux/Windows全攻略

EMQX开源版安装教程-linux/windows 因最近自己需要使用MQTT&#xff0c;需要搭建一个MQTT服务器&#xff0c;所以想到了很久以前用到的EMQX。但是当时的EMQX使用的是开源版的&#xff0c;在官网可以直接下载。而现在再次打开官网时发现怎么也找不大开源版本了&#xff0c;所以…...

MySQL 数据库备份与还原

作者&#xff1a;IvanCodes 日期&#xff1a;2025年5月18日 专栏&#xff1a;MySQL教程 思维导图 备份 (Backup) 与 冗余 (Redundancy) 的核心区别: &#x1f3af; 备份是指创建数据的副本并将其存储在不同位置或介质&#xff0c;主要目的是在发生数据丢失、损坏或逻辑错误时进…...

【数据结构】2-3-4 单链表的建立

数据结构知识点合集 尾插法建立单链表 建立链表时总是将新节点插入到链表的尾部&#xff0c;将新插入的节点作为链表的尾节点 /*尾插法建立链表L*/ LinkList List_TailInsert(LinkList &L) { int x; /*建立头节点*/ L (LNode *)malloc(sizeof(LNode)); /*…...

JVM如何处理多线程内存抢占问题

目录 1、堆内存结构 2、运行时数据 3、内存分配机制 3.1、堆内存结构 3.2、内存分配方式 1、指针碰撞 2、空闲列表 4、jvm内存抢占方案 4.1、TLAB 4.2、CAS 4.3、锁优化 4.4、逃逸分析与栈上分配 5、问题 5.1、内存分配竞争导致性能下降 5.2、伪共享&#xff08…...

猫番阅读APP:丰富资源,优质体验,满足你的阅读需求

猫番阅读APP是一款专为书籍爱好者设计的移动阅读应用&#xff0c;致力于提供丰富的阅读体验和多样化的书籍资源。它不仅涵盖了小说、非虚构、杂志等多个领域的电子书&#xff0c;还提供了个性化推荐、书架管理、离线下载等功能&#xff0c;满足不同读者的阅读需求。无论是通勤路…...

Redis 学习笔记 4:优惠券秒杀

Redis 学习笔记 4&#xff1a;优惠券秒杀 本文基于前文的黑马点评项目进行学习。 Redis 生成全局唯一ID 整个全局唯一 ID 的结构如下&#xff1a; 这里的时间戳是当前时间基于某一个基准时间&#xff08;项目开始前的某个时间点&#xff09;的时间戳。序列号是依赖 Redis 生…...

C++学习:六个月从基础到就业——C++17:if/switch初始化语句

C学习&#xff1a;六个月从基础到就业——C17&#xff1a;if/switch初始化语句 本文是我C学习之旅系列的第四十六篇技术文章&#xff0c;也是第三阶段"现代C特性"的第八篇&#xff0c;主要介绍C17引入的if和switch语句的初始化表达式特性。查看完整系列目录了解更多内…...

C++跨平台开发经验与解决方案

在当今软件开发领域&#xff0c;跨平台开发已成为一个重要的需求。C作为一种强大的系统级编程语言&#xff0c;在跨平台开发中扮演着重要角色。本文将分享在实际项目中的跨平台开发经验和解决方案。 1. 构建系统选择 CMake的优势 跨平台兼容性好 支持多种编译器和IDE 强大…...

RabbitMQ 工作模式(上)

前言 在 RabbitMQ 中&#xff0c;一共有七种工作模式&#xff0c;我们也可以打开官网了解&#xff1a; 本章我们先介绍前三种工作模式 &#xff08;Simple&#xff09;简单模式 P&#xff1a;producer 生产者&#xff0c;负责发送消息 C&#xff1a;consumer 消费者&#x…...

为什么需要加密机服务?

前言 大家好&#xff0c;我是老马。 以前我自己在写工具的时候&#xff0c;都是直接自己实现就完事了。 但是在大公司&#xff0c;或者说随着合规监管的要求&#xff0c;自己随手写的加解密之类的&#xff0c;严格说是不合规的。 作为一家技术性公司&#xff0c;特别是金融…...

【Linux】利用多路转接epoll机制、ET模式,基于Reactor设计模式实现

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 上篇文章&#xff1a;多路转接epoll&#xff0c;实现echoserver 至此&#xff0c;Linux与…...

c/c++的findcontours崩溃解决方案

解决 Windows 平台 OpenCV findContours 崩溃&#xff1a;一种更稳定的方法 许多在 Windows 平台上使用 OpenCV 的开发者可能会在使用 findContours 函数时&#xff0c;遇到令人头疼的程序崩溃问题。尽管网络上流传着多种解决方案&#xff0c;但它们并非总能根治此问题。 当时…...

机器学习 Day18 Support Vector Machine ——最优美的机器学习算法

1.问题导入&#xff1a; 2.SVM定义和一些最优化理论 2.1SVM中的定义 2.1.1 定义 SVM 定义&#xff1a;SVM&#xff08;Support Vector Machine&#xff0c;支持向量机&#xff09;核心是寻找超平面将样本分成两类且间隔最大 。它功能多样&#xff0c;可用于线性或非线性分类…...

npm与pnpm--为什么推荐pnpm

包管理器中 npm是最经典的&#xff0c;但大家都任意忽略一个更优质的管理器&#xff1a;pnpm 1. 核心区别 特性npmpnpm依赖存储方式扁平化结构&#xff08;可能重复依赖&#xff09;硬链接 符号链接&#xff08;共享依赖&#xff0c;节省空间&#xff09;安装速度较慢&#…...

ollama调用千问2.5-vl视频图片UI界面小程序分享

1、问题描述&#xff1a; ollama调用千问2.5-vl视频图片内容&#xff0c;通常用命令行工具不方便&#xff0c;于是做了一个python UI界面与大家分享。需要提前安装ollama&#xff0c;并下载千问qwen2.5vl:7b 模型&#xff0c;在ollama官网即可下载。 &#xff08;8G-6G 显卡可…...

济南国网数字化培训班学习笔记-第三组-1-电力通信传输网认知

电力通信传输网认知 电力通信基本情况 传输介质 传输介质类型&#xff08;导引与非导引&#xff09; 导引传输介质&#xff0c;如电缆、光纤&#xff1b; 非导引传输介质&#xff0c;如无线电波&#xff1b; 传输介质的选择影响信号传输质量 信号传输模式&#xff08;单工…...