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

生产者和消费者问题

生产者和消费者问题 Synchronized 版

/*** 线程之间的通信问题:生产者和消费者问题! 等待 通知唤醒* 线程交替执行 A B 操作同一个变量 num = 0* A num+1* B num-1*/public class A {public static void main(String[] args) {Data1 data = new Data1();new Thread(() -> {for (int i = 0; i < 10; i++) {data.increment();}}, "A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data.decrement();}}, "B").start();}}// 判断等待,业务,通知
class Data1 {private Integer num = 0;// +1 生产public synchronized void increment() {if (num != 0) {// 等待try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}num++;System.out.println(Thread.currentThread().getName() + "=>" + num);// 通知其他线程,我+1完毕了this.notifyAll();}// -1 消费public synchronized void decrement() {if (num == 0) {// 等待try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}num--;System.out.println(Thread.currentThread().getName() + "=>" + num);// 通知其他线程,我-1完毕了this.notifyAll();}}

问题存在,A B C D 4 个线程! 虚假唤醒

多线程环境的编程中,我们经常遇到让多个线程等待在一个条件上,等到这个条件成立的时候我们再去唤醒这些线程,让它们接着往下执行代码的场景。假如某一时刻条件成立,所有的线程都被唤醒了,然后去竞争锁,因为同一时刻只会有一个线程能拿到锁,其他的线程都会阻塞到锁上无法往下执行,等到成功争抢到锁的线程消费完条件,释放了锁,后面的线程继续运行,拿到锁时这个条件很可能已经不满足了,这个时候线程应该继续在这个条件上阻塞下去,而不应该继续执行,如果继续执行了,就说发生了虚假唤醒。

把if判断换成了while判断

public class A {public static void main(String[] args) {Data1 data = new Data1();new Thread(() -> {for (int i = 0; i < 10; i++) {data.increment();}}, "A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data.decrement();}}, "B").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data.increment();}}, "C").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data.decrement();}}, "D").start();}}// 判断等待,业务,通知
class Data1 {private Integer num = 0;// +1 生产public synchronized void increment() {while (num != 0) {// 等待try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}num++;System.out.println(Thread.currentThread().getName() + "=>" + num);// 通知其他线程,我+1完毕了this.notifyAll();}// -1 消费public synchronized void decrement() {while (num == 0) {// 等待try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}num--;System.out.println(Thread.currentThread().getName() + "=>" + num);// 通知其他线程,我-1完毕了this.notifyAll();}}

JUC版的生产者和消费者问题

public class B {public static void main(String[] args) {Data2 data = new Data2();new Thread(() -> {for (int i = 0; i < 10; i++) {data.increment();}}, "A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data.decrement();}}, "B").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data.increment();}}, "C").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data.decrement();}}, "D").start();}}// 判断等待,业务,通知
class Data2 {private Integer num = 0;private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();// +1 生产public void increment() {lock.lock();try {while (num != 0) {// 等待condition.await();}num++;System.out.println(Thread.currentThread().getName() + "=>" + num);// 通知其他线程,我+1完毕了condition.signalAll();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}// -1 消费public synchronized void decrement() {lock.lock();try {while (num == 0) {// 等待condition.await();}num--;System.out.println(Thread.currentThread().getName() + "=>" + num);// 通知其他线程,我-1完毕了condition.signalAll();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}}

Condition 精准的通知和唤醒线程

/*** A 执行完调用B,B执行完调用C,C执行完调用A*/
public class C {public static void main(String[] args) {Data3 data = new Data3();new Thread(() -> {for (int i = 0; i < 10; i++) {data.printA();}}, "A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data.printB();}}, "B").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data.printC();}}, "C").start();}}// 判断等待,业务,通知
class Data3 {private Integer num = 1; // 1A 2B 3Cprivate Lock lock = new ReentrantLock();private Condition condition1 = lock.newCondition();private Condition condition2 = lock.newCondition();private Condition condition3 = lock.newCondition();public void printA() {lock.lock();try {while (num != 1) {// 等待condition1.await();}System.out.println(Thread.currentThread().getName() + " => AAAAAA");num = 2;// 唤醒,唤醒指定的人,Bcondition2.signal();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}public void printB() {lock.lock();try {while (num != 2) {// 等待condition2.await();}System.out.println(Thread.currentThread().getName() + " => BBBBBB");num = 3;// 唤醒,唤醒指定的人,Ccondition3.signal();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}public void printC() {lock.lock();try {while (num != 3) {// 等待condition3.await();}System.out.println(Thread.currentThread().getName() + " => CCCCCC");// 唤醒,唤醒指定的人,Anum = 1;condition1.signal();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}}
http://www.xdnf.cn/news/615889.html

相关文章:

  • C++可变参数宏定义语法笔记
  • 【数据架构01】数据技术架构篇
  • Dify聊天系统SSE响应和聊天树数据结构图解
  • Spring的组成部分
  • Linux 的OTA升级学习1:Linux OTA升级方案_SWupdate
  • 聚焦 Microsoft Fabric,释放数据潜力
  • 篇一:重新学习的碎碎记
  • 【Web前端】JavaScript入门与基础(二)
  • 【AS32X601驱动系列教程】USART_串口通讯详解
  • 传统工程项目管理与业财一体化管理的区别?
  • 【知识点】关于vue3中markRow、shallowRef、shallowReactive的了解
  • [20250522]目前市场上主流AI开发板及算法盒子的芯片配置、架构及支持的AI推理框架的详细梳理
  • 深入解析 Linux 进程管理
  • 智能建筑时代来临,楼宇自控技术成智能建筑标配新趋势
  • redis主从复制架构安装与部署
  • 【跨端框架检测】使用adb logcat检测Android APP使用的跨端框架方法总结
  • 【通用智能体】Intelligent Internet Agent (II-Agent):面向复杂网络任务的智能体系统深度解析
  • 1.1 自动控制的一般概念
  • 【自定义类型-联合和枚举】--联合体类型,联合体大小的计算,枚举类型,枚举类型的使用
  • 电脑 IP 地址修改工具,轻松实现异地登陆
  • 如何实现 ERP 系统与淘宝订单、商品、物流接口对接
  • 大厂技术大神远程 3 年,凌晨 1 点到 6 点竟开会 77 次。同事一脸震惊,网友:身体还扛得住吗?
  • swagger-mcp-server
  • 《GDB 调试实战指南:无源码程序分析技巧与命令详解》
  • P3205 [HNOI2010] 合唱队
  • AI 驱动近红外光谱预处理:从数据清洗到特征工程的自动化
  • 2025版CansCodeAPI管理系统:免费下载,全新升级!
  • 八股--SSM(2)
  • 海外交友APP语言切换模块设计
  • 【AI大模型研究报告】2024年中国工业大模型行业发展研究报告