使用Java的等待/通知机制实现一个简单的阻塞队列
Java的等待/通知机制
Java的等待通知机制是多线程间进行通信的一种方式。
有三个重要的方法:wait(),notify() 和以及notifyAll()
- wait():该方法用于让当前线程(即调用该方法的线程)进入等待状态并且释放掉该对象上的锁。而这个线程会在以下三种情况下从 wait() 返回到执行状态:
- 其他线程调用了同一个对象的 notify() 方法。
- 其他线程调用了同一个对象的 notifyAll() 方法。
- 其他线程调用了该线程的 interrupt() 方法,线程收到中断信号。
- notify():唤醒在此对象监视器上等待的单个线程,选择其唤醒的线程是任意的,并且是随机的。唤醒后,等待线程会尝试重新获取锁并继续执行。
- notifyAll():唤醒在此对象监视器上等待的所有线程。
实现阻塞队列
我们就是使用这几个方法来实现了一个简单的阻塞队列,借助生产者-消费者模型来构建更方便理解。而且是较为简单的单个生产者和单个消费者。
我们有一个容量是n的仓库,起初仓库是空的,此时消费者来消费是不可以的,因此就被阻塞,而当生产者生产了一个物品之后,就会调用notify,唤醒在此对象监视器上等待的单个线程(消费者)。当仓库是满的时候,此时生产者再生产也是不行的,也会被阻塞,此时当消费消费之后,也会调用notify唤醒在此对象监视器上等待的单个线程(生产者)。
import java.util.*;public class BlockQ<T> {// 队列的最大容量static final int MAX_CAPACITY = 10;// 队列的默认容量static final int DEFAULT_CAPACITY = 5;// 队列的最小容量static final int MIN_CAPACITY = 1;// 队列(仓库,仓库不满生产者才能生产,仓库不空消费者才能消费)private Queue<T> q = new LinkedList<>();// 队列的容量private int capacity;public BlockQ(){this.capacity = DEFAULT_CAPACITY;}public BlockQ(int capacity){this.capacity = Math.min(MAX_CAPACITY, Math.max(MIN_CAPACITY, capacity));}public void addT(T record) throws InterruptedException {synchronized (q){while(q.size() == this.capacity){System.out.println("size:" + q.size() + ",records:" + Arrays.toString(q.toArray()));// 该线程等待,并释放q上的锁q.wait();}System.out.println("生产者生产的数字: " + record);q.offer(record);// 唤醒一个在q上等待的线程q.notify();}}public T getT() throws InterruptedException {synchronized (q){while(q.size() == 0){System.out.println("size:" + q.size() + ",records:" + Arrays.toString(q.toArray()));q.wait();}T res = q.poll();System.out.println("消费者获取到数字: " + res);q.notify();return res;}}
}
测试
我们创建了两个线程,一个生产者线程,一个消费者线程。在主线程中设置Thread.sleep(7000),是为了让生产者先生产,然后我们也能提前看见生产者被阻塞。而后面也会出现消费者被阻塞的情况,这些都是系统设置的时间片,我们无法改变。但是我们可以设置生产者生产和消费者消费的速率,也即修改各自线程中的沉睡时间,这样我们就能看见生产者被阻塞,或者消费者被阻塞。
public class Test {static BlockQ<Integer> queue = new BlockQ<>(4);public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new ProducerThread());Thread t2 = new Thread(new ConsumerThread());t1.start();Thread.sleep(7000);t2.start();}
}/*** 生产者*/
class ProducerThread implements Runnable{private int cnt = 0;@Overridepublic void run() {while (true) {try {Test.queue.addT(cnt ++);Thread.sleep(800);} catch (InterruptedException e) {e.printStackTrace();}}}
}/*** 消费者*/
class ConsumerThread implements Runnable{@Overridepublic void run() {while (true) {try {Integer i = Test.queue.getT();Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}
}
运行结果

运行的时候,这里等待了几秒才出现以下内容,跟自己在主线程设置的的沉睡时间有关

相关文章:
使用Java的等待/通知机制实现一个简单的阻塞队列
Java的等待/通知机制 Java的等待通知机制是多线程间进行通信的一种方式。 有三个重要的方法:wait(),notify() 和以及notifyAll() wait():该方法用于让当前线程(即调用该方法的线程)进入等待状态并且释放掉该对象上的…...
linux kernel物理内存概述(七)
目录 一、内核中小内存、频繁分配和释放场景 二、slab是内存池化技术 三、内核中使用slab对象池的地方 四、slab内核设计 使用比页小的内存,内核的处理方式使用slab 一、内核中小内存、频繁分配和释放场景 slab首先会向伙伴系统一次性申请一个或者多个物理内存…...
【C#】.net core 6.0 使用第三方日志插件Log4net,日志输出到控制台或者文本文档
欢迎来到《小5讲堂》 大家好,我是全栈小5。 这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。…...
TSINGSEE青犀煤矿矿井视频监控与汇聚融合管理视频监管平台建设方案
一、背景需求 随着我国经济的飞速发展,煤炭作为我国的主要能源之一,其开采和利用的重要性不言而喻。然而,煤矿事故频发,不仅造成了巨大的人员伤亡和财产损失,也对社会产生了深远的负面影响。视频监控系统作为实现煤矿智…...
C语言 - 各种自定义数据类型
1.结构体 把不同类型的数据组合成一个整体 所占内存长度是各成员所占内存的总和 typedef struct XXX { int a; char b; }txxx; txxx data; typedef struct XXX { int a:1; int b:1; …...
第四弹:Flutter图形渲染性能
目标: 1)Flutter图形渲染性能能够媲美原生? 2)Flutter性能优于React Native? 一、Flutter图形渲染原理 1.1 Flutter图形渲染原理 Flutter直接调用Skia 1)Flutter将一帧录制成SkPicture(skpÿ…...
基础算法(三)#蓝桥杯
文章目录 11、构造11.1、小浩的ABC11.2、小新的质数序列挑战11.3、小蓝找答案11.4、小蓝的无限集 12、高精度12.1、阶乘数码(高精度*单精度) 11、构造 11.1、小浩的ABC #include<bits/stdc.h> using namespace std; #define IOS ios::sync_with_stdio(false);cin.tie(n…...
人工智能在增强数据安全方面的作用
近年来,人工智能(AI)的力量已被证明是无与伦比的。它不再是我们想象的主题。人工智能已经成为现实,并且越来越清楚地表明它可以让世界变得更美好。但人工智能能帮助我们增强数据安全吗? 由于技术的日益普及࿰…...
python】jupyter notebook导出pdf和pdf不显示中文问题
安装nbconvert 首先安装nbconvert才能将.ipynb文件转化为pdf、latex、html等。 conda install nbconvert安装Pandoc Pandoc官网下载地址: https://pandoc.org/installing.html 下载安装包github地址:https://github.com/jgm/pandoc/releases/tag/3.1.6.2 安装MiKTex 下载…...
通过SDKMAN安装各种版本JDK
文章目录 1. 安装SDKMAN管理器2. 通过SDK管理器安装JDK3. 参考链接 1. 安装SDKMAN管理器 安装SDKMAN的脚本为: # 1.1 安装: 如果没有权限可以考虑sudo用户执行; curl -s "https://get.sdkman.io" | bash# 1.2 安装完成后查看版本号 sdk version# 1.3 查看帮助信息 …...
软考高级:软件架构风格概念和例题
作者:明明如月学长, CSDN 博客专家,大厂高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《Effective Java》独家解析》专栏作者。 热门文章推荐&am…...
Vue3响应式编程
Vue 3 的响应式系统是其核心特性之一,它允许开发者创建响应式的数据绑定和组件状态管理。在 Vue 3 中,响应式系统得到了显著的改进,提供了更好的性能和更灵活的使用方式。 1. 响应式原理 Vue 3 使用了 Proxy 对象来实现响应式系统ÿ…...
决策树算法优化(一篇文章 理解)
目录 引言 一、决策树的基本概念 二、决策树的构建过程 1 特征选择 2 决策树生成 3 决策树剪枝 三、决策树算法的缺点 1 过拟合问题 2 对噪声敏感 3 缺乏连续变量的处理 4 倾向于选择具有较多类别的特征 四、优化策略 1 集成学习 2 连续变量处理 3 特征选择优化 …...
【C语言步行梯】自定义函数、函数递归详谈
🎯每日努力一点点,技术进步看得见 🏠专栏介绍:【C语言步行梯】专栏用于介绍C语言相关内容,每篇文章将通过图片代码片段网络相关题目的方式编写,欢迎订阅~~ 文章目录 什么是函数库函数自定义函数函数执行示例…...
小米汽车上市进入倒计时,已开启内部试驾
在十四届全国人大二次会议上,全国人大代表、小米集团创始人、董事长CEO雷军回应了小米汽车的最新消息,小米汽车预计很快就要正式上市。 小米汽车推出了两款车型:SU7和SU7 Max。这两款车型均为纯电轿车,带来了不同的配置和性能特点…...
React render方法的原理?在什么时候会被触发?
一、原理 首先,render函数在react中有两种形式: 在类组件中,指的是render方法: class Foo extends React.Component {render() {return <div> Foo </div>;} } 在函数组件中,指的是函数组件本身&#x…...
打卡学习kubernetes——了解kubernetes组成及架构
目录 1 什么是kubernetes 2 kubernetes组件 3 kubernetes架构 1 什么是kubernetes kubernetes是一个旨在自动部署、扩展和运行应用容器的开源平台。目标是构建一个生态系统,提供组件和工具以减轻在公共和私有云中运行应用程序的负担。 kubernetes是:…...
python(ogr)处理geojson为本地shp文件
前言 本次所利用的geojson数据来自https://geo.datav.aliyun.com/areas_v3/bound/410000_full.json ,如果觉得下方代码看起来不方便,可以来GitHub上来看,在这上面还有一些辅助内容便于理解 GISpjd/GIS-union-Python (github.com)https://gi…...
Docker容器化技术(使用Dockerfile制作镜像)
Docker中的镜像分层 Docker 支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。 1、Docker 镜像为什么分层 镜像分层最大的一个好处就是共享资源。 比如说有多个镜像都从相…...
C++ struct 结构体类型
在处理大批量数据时,一般会使用数组来实现,数组中各元素都属于同一数据类型。但在实际问题中,要处理的一组数据往往具有不同的数据类型。如一个学生的个人信息有学号(num)、姓名(name)、性别&am…...
网易云音乐NCM转MP3终极指南:ncmdump工具完整使用教程
网易云音乐NCM转MP3终极指南:ncmdump工具完整使用教程 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾经从网易云音乐下载了心爱的歌曲,却发现只能在特定播放器上收听?NCM格式的限制让音乐…...
[智能体-69]:重新认知MCP:协议不生产智能,只是AI全域交互的标准化基石
MCP只是提供了大模型、编排调度、外部工具能够进行结构化交流的标准,而整个系统的智能主要依赖编排调度,与外部软件系统的交互取决于外部工具,包括外部语音交互、视觉交互、数字化交互。当下MCP(Model Context Protocol࿰…...
别再死记硬背Payload了!我用XSS-Game靶场,带你拆解18种过滤规则背后的绕过逻辑
从XSS-Game靶场实战中掌握18种过滤规则的逆向思维在网络安全领域,跨站脚本攻击(XSS)始终是Web应用面临的主要威胁之一。许多开发者虽然了解XSS的基本概念,但当面对各种复杂的过滤规则时,往往不知如何系统分析并构造有效…...
Python合并Excel文档
有若干个Excel文档,每个文档格式一致,及第一行为文件标题,第二行为表格表头(表头不完全一致)。现需要将他们合并。合并规则为:去掉每个文档的第一行,以第二行为表头,将每个文档的第三…...
【DeepSeek开源协议识别权威指南】:20年合规专家亲授3大协议陷阱与5步精准识别法
更多请点击: https://intelliparadigm.com 第一章:DeepSeek开源协议识别的底层逻辑与合规价值 DeepSeek系列模型(如DeepSeek-V2、DeepSeek-Coder)虽以“开源”名义发布,但其实际许可状态需通过结构化协议解析才能准确…...
新能源车轻量化为什么开始盯上高强镁合金?
续航,是悬在每一台纯电动汽车头上的达摩克利斯之剑。多充一度电、多堆一些正极材料,是一条路;但还有另一条路——把车造得更轻。 SAE(美国汽车工程师学会)的测算已经被反复引用:整车每减重100千克ÿ…...
METSO A413248自动化系统
METSO A413248 自动化系统模块产品特点: 品牌归属:芬兰METSO(美卓)工业自动化系统原装备件。 产品类型:工业级自动化控制模块/接口模块。 核心功能:用于控制信号处理、数据采集及系统集成。 系统兼容&am…...
【MySQL数据库 | 第一篇】 概述
数据库相关概念: 数据库(Database):数据库是指一组有组织的数据的集合,通过计算机程序进行管理和访问。数据库管理系统:操纵和管理数据库的大型软件SQL:操作关系型数据库的编程语言,定义了一套操作关系型数…...
氘可来昔替尼常见副作用为鼻咽炎头痛及腹泻,如何应对
任何口服药物的临床价值,都必须在疗效与安全性的天平上找到精准的平衡点。氘可来昔替尼以PASI 75应答率的全面胜出证明了自己在银屑病治疗中的卓越地位,而其不良反应谱同样经过了严苛的临床验证。鼻咽炎、头痛和腹泻构成了这款药物最需关注的三大安全信号…...
告别手动预约:i茅台自动预约系统5分钟部署指南
告别手动预约:i茅台自动预约系统5分钟部署指南 【免费下载链接】campus-imaotai i茅台app自动预约,每日自动预约,支持docker一键部署(本项目不提供成品,使用的是已淘汰的算法) 项目地址: https://gitcode…...
