使用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…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
