JAVA 100道题(22)

22.实现一个生产者-消费者问题,使用Java的线程同步机制。

生产者-消费者问题是一个经典的并发编程问题,其中生产者产生数据(或产品),消费者消费这些数据。在Java中,我们可以使用wait()notify()方法或者BlockingQueue接口来实现线程同步。

以下是使用wait()notify()方法实现的生产者-消费者问题的示例:

 

java复制代码

public class ProducerConsumerExample {
private static final int MAX_SIZE = 10; // 缓冲区大小
private static final Object lock = new Object(); // 锁对象
private static List<Integer> buffer = new ArrayList<>(MAX_SIZE); // 缓冲区
private static int count = 0; // 缓冲区中当前元素的数量
// 生产者线程
static class Producer extends Thread {
public void run() {
while (true) {
synchronized (lock) {
// 等待缓冲区不满
while (count == MAX_SIZE) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 生产一个产品(这里用随机数表示)
int product = (int) (Math.random() * 100);
buffer.add(product);
count++;
// 通知可能等待的消费者线程
lock.notifyAll();
}
// 休眠一段时间,模拟生产速度
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 消费者线程
static class Consumer extends Thread {
public void run() {
while (true) {
synchronized (lock) {
// 等待缓冲区不空
while (count == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 消费一个产品
int product = buffer.remove(0);
count--;
// 通知可能等待的生产者线程
lock.notifyAll();
}
// 休眠一段时间,模拟消费速度
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
// 创建并启动生产者线程
new Producer().start();
// 创建并启动消费者线程
new Consumer().start();
}
}

在上面的代码中,我们定义了一个Producer类和一个Consumer类,它们分别继承了Thread类并重写了run()方法。生产者会向缓冲区中添加产品,而消费者会从缓冲区中取出产品。我们使用一个共享的lock对象来实现同步,以及wait()notifyAll()方法来协调生产者和消费者之间的操作。

注意,在生产者和消费者的run()方法中,我们使用了一个while循环来检查缓冲区是否满或空,而不是if条件判断。这是因为wait()方法可能会因为其他原因(如interrupt())被唤醒,所以我们需要再次检查条件是否满足。

此外,为了避免死锁和活锁,确保在wait()notify()方法调用前后都持有锁。这是因为在调用wait()方法时,线程会释放锁,而notify()notifyAll()方法调用后,其他线程可能会获取锁并继续执行。

尽管上述示例展示了如何使用基本的线程同步机制实现生产者-消费者问题,但在实际开发中,通常更推荐使用Java并发包中的BlockingQueue接口及其实现类(如ArrayBlockingQueueLinkedBlockingQueue等),因为它们提供了更简洁、更安全的线程同步机制。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解密EMC与EMI:电磁兼容性与电磁干扰?|深圳比创达电子

在现代电子设备愈发普及的时代&#xff0c;EMC&#xff08;Electromagnetic Compatibility&#xff09;和EMI&#xff08;Electromagnetic Interference&#xff09;成为了不容忽视的重要议题。本文将从根本概念出发&#xff0c;逐步深入探讨这两个关键领域&#xff0c;带领各位…

【信贷后台管理之登录(一)】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录结构一、项目搭建二、登录页面1.引入Element-ui2.LoginView.vue组件3.router文件的index.js引入组件 gitee仓库地址 目录结构 一、项目搭建 找到存放项目的文件…

解析旅游者心声:用PySpark和SnowNLP揭秘景区评论的情感秘密

简介: 在本篇博客中,我们将探讨如何利用PySpark和SnowNLP这两个强大的工具来分析大规模的旅游评论数据。通过结合携程和去哪儿的数据作为示例,我们将探索如何从海量的评论中提取有价值的情感信息和洞察。PySpark作为一种分布式计算框架,能够处理大规模的数据集,为我们提供…

Java服务运行在Linux----维护常用命令

想起来哪些再添加上去 查看Java程序进程 jps -l 查出进程后根据pid 查询程序所在目录 pwdx 31313 根据端口查找PID 根据pid杀死程序 kill -p 31313 查看目录下所有包含9527的文件 grep -rn 9527 查看磁盘空间 查找文件名"nginx"文件或模糊查找"*nginx*&quo…

Mysql中如何显示第几周

在数据分析中&#xff0c;经常需要对日期和时间进行格式化处理&#xff0c;以便更直观地展示和理解数据。 MySQL 5.7提供了强大的DATE_FORMAT函数&#xff0c;允许用户根据特定的格式字符串来显示日期和时间。 Week函数 最直接的是使用YEAR、WEEK函数 SELECTYEAR(NOW()) AS C…

健身运动耳机哪个牌子好?力荐五大品质翘楚的精品

健身已经成为许多人追求健康与活力的重要方式&#xff0c;而在健身的过程中&#xff0c;一款优质的耳机不仅能让你沉浸于音乐的世界&#xff0c;更能提升运动体验&#xff0c;激发无限潜能&#xff0c;那么如何选择一款既适合运动又品质卓越的耳机呢&#xff1f;今天我这个健身…

【热门话题】Yarn:新一代JavaScript包管理器的安装与使用

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Yarn&#xff1a;新一代JavaScript包管理器的安装与使用引言一、Yarn的安装1. 系…

element-ui inputNumber 组件源码分享

今日简单分享 inputNumber 组件的实现原理&#xff0c;主要从以下四个方面来分享&#xff1a; 1、inputNumber 组件的页面结构 2、inputNumber 组件的属性 3、inputNumber 组件的事件 4、inputNumber 组件的方法 一、inputNumber 组件的页面结构。 二、inputNumber 组件的…

linux安装Zookeeper的详细步骤

1.Java环境确认 确保已经安装了Java环境&#xff0c;没有的自行安装 2.官网下载包 Apache ZooKeeper 3.安装 3.1上传到linux&#xff0c;解压 我的目录为/root/apache-zookeeper-3.8.4-bin 进入到/root/apache-zookeeper-3.8.4-bin/conf目录下&#xff0c;执行命令复制zoo…

由浅到深认识Java语言(44):Junit单元测试

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

硬件12、PCB模块化布局

模块画布局其实就是根据原理图中绘制的小模块&#xff0c;比如3.3V芯片及其外围电路部分的元器件在PCB中放在一起进行布线&#xff0c;会方便很多 1、最好打开分屏&#xff0c;一边在原理图中选中模块&#xff0c;一边在PCB中绘制 2、选中原理图中的模块的所有元件&#xff0…

工业智能物联网关如何助力工业防震减灾

地震灾害难以预料&#xff0c;一旦发生往往就损失重大。对于工业领域而言&#xff0c;地震灾害的影响不仅仅是对人员安全的威胁&#xff0c;还包括对生产设施的破坏、生产进程的中断以及伴生的持续性经济损失。 随着5G、大数据、物联网技术的发展&#xff0c;面向工业领域构建一…

有效的数独-java

题目描述: 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&#…

python如何获取word文档的总页数

最近在搞AI. 遇到了一个问题&#xff0c;就是要进行doc文档的解析。并且需要展示每个文档的总页数。 利用AI. 分别尝试了chatGPT, 文心一言&#xff0c; github copilot&#xff0c;Kimi 等工具&#xff0c;给出来的答案都不尽如人意。 给的最多的查询方式就是下面这种。 这个…

代码随想录阅读笔记-二叉树【翻转二叉树】

题目 翻转一棵二叉树。 思路 如果要从整个树来看&#xff0c;翻转还真的挺复杂&#xff0c;整个树以中间分割线进行翻转&#xff0c;如图&#xff1a; 可以发现想要翻转它&#xff0c;其实就把每一个节点的左右孩子交换一下就可以了。 关键在于遍历顺序&#xff0c;前中后序应…

如何通过vscode连接到wsl

下载wsl扩展 远程连接模式

SQL Server 实验二:数据库视图的创建和使用

目录 第一关 相关知识 什么是表 操作数据表 创建数据表 插入数据 修改表结构 删除数据表 编程要求 第一关实验代码&#xff1a; 第二关 相关知识 视图是什么 视图的优缺点 视图的优点 视图的缺点 操作视图 创建视图 通过视图向基本表中插入数据 通过视图修改基本表的…

Selenium元素定位之页面检测技巧

在进行web自动化测试的时候进行XPath或者CSS定位&#xff0c;需要检测页面元素定位是否正确&#xff0c;如果用脚本去检测&#xff0c;那么效率是极低的。 一般网上推选装额外的插件来实现页面元素定位检测 如&#xff1a;firebug。 其实F12开发者工具就能直接在页面上检测元…

JavaScript new一个对象的详细过程

JavaScript new一个对象的详细过程 new实现过程 new实现原理 new手写实现 实现过程/原理 开辟一块内存&#xff0c;创建一个空对象 执行构造函数对这个空对象进行构造 给空对象添加__proto__属性 调用函数改变this指向 最后返回this指向的新对象&#xff08;如果是引用类型则返…

C# OpenCvSharp MatchTemplate 多目标匹配

目录 效果 项目 代码 下载 效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenCvSharp; using O…
最新文章