深入讲解Java线程中 wait 和 notify 的用法和原理

基本概念

waitnotify 是 Java 中用于线程间通信的方法,定义在 Object 类中。它们的主要作用是在多线程环境中协调线程的执行顺序。

wait 方法

  • 作用:使当前线程进入等待状态,直到其他线程调用 notifynotifyAll 方法唤醒它。
  • 调用条件:必须在同步块或同步方法中调用,因为调用 wait 方法的线程需要持有对象的监视器锁(即对象锁)。
  • 锁释放:调用 wait 方法时,当前线程会释放对象的监视器锁,并进入该对象的等待队列中。
synchronized (lock) {while (!condition) {lock.wait();}// 执行后续操作
}

notify 方法

  • 作用:唤醒在该对象的等待队列中等待的一个线程。如果有多个线程在等待,选择其中一个线程唤醒。
  • 调用条件:必须在同步块或同步方法中调用,因为调用 notify 方法的线程需要持有对象的监视器锁。
synchronized (lock) {condition = true;lock.notify();
}

notifyAll 方法

  • 作用:唤醒在该对象的等待队列中等待的所有线程。
  • 调用条件:必须在同步块或同步方法中调用,因为调用 notifyAll 方法的线程需要持有对象的监视器锁。
synchronized (lock) {condition = true;lock.notifyAll();
}

使用场景:生产者-消费者模式

生产者-消费者模式是 waitnotify 方法的经典应用场景。在这种模式下,生产者线程生成数据,消费者线程消费数据,waitnotify 方法用于协调它们的工作。

示例代码
 
class SharedResource {private int content;private boolean available = false;public synchronized void put(int value) {while (available) {try {wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}content = value;available = true;notify();}public synchronized int get() {while (!available) {try {wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}available = false;notify();return content;}
}class Producer implements Runnable {private SharedResource resource;public Producer(SharedResource resource) {this.resource = resource;}public void run() {for (int i = 0; i < 10; i++) {resource.put(i);System.out.println("Produced: " + i);try {Thread.sleep((int) (Math.random() * 100));} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}class Consumer implements Runnable {private SharedResource resource;public Consumer(SharedResource resource) {this.resource = resource;}public void run() {for (int i = 0; i < 10; i++) {int value = resource.get();System.out.println("Consumed: " + value);try {Thread.sleep((int) (Math.random() * 100));} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}public class ProducerConsumerTest {public static void main(String[] args) {SharedResource resource = new SharedResource();Thread producerThread = new Thread(new Producer(resource));Thread consumerThread = new Thread(new Consumer(resource));producerThread.start();consumerThread.start();}
}

运行效果

这段代码展示了生产者和消费者如何通过 waitnotify 方法进行协调:

Produced: 0
Consumed: 0
Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
...

详细解释

  1. 生产者线程

    • 生产者线程调用 put 方法试图放入一个值。
    • 如果 availabletrue(表示已有未被消费的数据),生产者线程调用 wait 方法进入等待状态,直到消费者消费了数据并唤醒它。
    • 如果 availablefalse,生产者线程放入新值,设置 availabletrue,并调用 notify 方法唤醒一个等待的消费者线程。
  2. 消费者线程

    • 消费者线程调用 get 方法试图获取一个值。
    • 如果 availablefalse(表示没有可消费的数据),消费者线程调用 wait 方法进入等待状态,直到生产者放入新数据并唤醒它。
    • 如果 availabletrue,消费者线程获取值,设置 availablefalse,并调用 notify 方法唤醒一个等待的生产者线程。

总结

  • wait:使当前线程进入等待状态,释放对象的监视器锁。
  • notify:唤醒一个在该对象上等待的线程。
  • notifyAll:唤醒所有在该对象上等待的线程。
  • 同步块/同步方法waitnotifynotifyAll 必须在同步块或同步方法中调用,因为它们需要当前线程持有对象的监视器锁。
  • 生产者-消费者模式:经典的 waitnotify 用例,展示了如何协调多个线程对共享资源的访问。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c linux 静态库试验

1.概要 2.代码 2.1 main.c #include <stdio.h> #include "add.h"int main(){printf("hello word\n");int a fun(3,5);printf("%d\n",a);return 0; } 2.2 add.c #include "add.h"int fun(int a,int b){return ab; } 2.3 a…

7号楼地面东照西和南照北

里面有个小交换机 断电重启下

labelme安装(通过anaconda)

1.下载安装anaconda 2.安装完成后打开&#xff0c;在环境页里面创建环境 选择3.6.13版本&#xff0c;然后运行 3.安装labelme pip install labelme -i https://pypi.tuna.tsinghua.edu.cn/simple 使用上面命令加速一下 4.labelme打开并标注 总结&#xff1a;现在版本越来越多…

中小学一级教师相当于什么级别的职称

你知道吗&#xff1f;当你一步步攀登职称的阶梯&#xff0c;达到中小学一级教师的荣誉时&#xff0c;你究竟站在了哪个高度&#xff1f;一级教师不仅是一个职称的标签&#xff0c;更是对你专业能力的认可。 中小学教师的职称体系&#xff0c;就像一幅层次分明的画卷&#xff0c…

vue3.0(十三)内置组件Transition和TransitionGroup

文章目录 简介一、<Transition> 组件1.基本应用2.动画过程中发生的事情3.基于 CSS 的过渡效果4.JavaScript 钩子5.可复用过渡效果6.出现时过渡7.元素间过渡8.过渡模式9.组件间过渡10.动态过渡11.使用 Key Attribute 过渡 二、<TransitionGroup>组件1.​​进入 / 离…

Blender:渲染输出

渲染输出界面 渲染设置界面&#xff1a; 输出设置界面&#xff1a; 输出文件格式 【文档】 视频导出格式&#xff1a; AVI JPEG 使用JPEG压缩的AVI。有损&#xff0c;能得到更小的文件&#xff0c;但大小无法与编解码器的压缩算法得到的文件相比。JPEG 压缩也是数字摄像机使用…

开源项目-MES制造执行系统

哈喽,大家好,今天主要给大家带来一个开源项目-制造执行系统 制造执行系统的主要功能包括系统管理,物料管理,工艺管理,计划管理,在制品管理,数字化平台,数字孪生等模块 <

知识图谱的应用---新零售

文章目录 新零售知识图谱构建过程典型应用 新零售 新零售&#xff0c;即个人、企业以互联网为依托&#xff0c;通过运用大数据、人工智能等先进技术手段并运用心理学知识&#xff0c;对商品的生产、流通与销售过程进行升级改造&#xff0c;进而重塑业态结构与生态圈&#xff0c…

精准定位,智慧提纯:高级数据提取策略

在数据驱动的时代&#xff0c;高级数据提取策略成为企业决策、科学研究以及各类项目成功的关键。数据提取&#xff0c;不仅仅是简单地收集信息&#xff0c;而是需要精准定位目标数据&#xff0c;并通过智慧提纯方法&#xff0c;从海量数据中提取出有价值、有深度的信息。本文将…

Redis之线程IO模型

引言 Redis是个单线程程序&#xff01;这点必须铭记。除了Redis之外&#xff0c;Node.js也是单线程&#xff0c;Nginx也是单线程&#xff0c;但是他们都是服务器高性能的典范。 Redis单线程为什么能够这么快&#xff01; 因为他所有的数据都在内存中&#xff0c;所有的运算都…

【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)

最终效果 文章目录 最终效果前言素材下载简单搭建环境控制小鸟生成弹簧 限制小鸟的控制范围弹簧线的显示隐藏飞行新增木头木头销毁不同血量的木头状态配置更多物品爆炸效果创建敌人的小猪创建多个小鸟循环游戏结束相机跟随加分特效不同定义技能的鸟加速鸟回旋鸟爆炸鸟效果 轨迹…

小学生作文辅导杂志小学生作文辅导杂志社小学生作文辅导编辑部2024年第2期目录

写法导引 创意引航&#xff0c;笔墨生辉——小学语文习作教学中的创新思维训练 杜娟; 3-5 陶行知“小先生制”教育思想在小学作文练习中的应用探索 张淑勤; 6-8 新课程标准视域下小学语文习作教学策略探析 任真真; 9-11 即时作文&#xff1a;开辟小学习作教学的…

Spring Boot集成 Spring Retry 实现容错重试机制并附源码

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

MATLAB神经网络---激活层

非线性变换的目的 非线性变换的目的是为神经网络引入一些非线性特征&#xff0c;使其训练出一些符合各种曲线或各种特征的模型。 换句话来说&#xff0c;如果模型都是直线特征的话&#xff0c;它的泛化能力会不够好。 目录 深度学习层列表 - MATLAB & Simulink - MathWo…

初识MySQL数据库

目录 一、了解数据库 1.数据库的相关概念 2.数据库系统发展史 3.主流数据库产品 二、数据库分类 1.关系数据库 2.非关系型数据库 三、mysql的yum安装与源码编译安装 1.源码编译安装mysql 2.yum安装 mysql5.7 四、MySQL数据类型 1.常用的数据类型 五、查看数据库…

高性能8位单片机 CA51M151,1T 8051内核 / 内置12位ADC / 16 位PWM / 支持触摸 / 8K MTP

CA51M151 系列芯片是基于 1T 8051 内核的 8 位微控制器&#xff0c;不仅保留了传统 8051 芯片的基本特性&#xff0c;通常情况下运行速度比传统的 8051 芯片快 10 倍&#xff0c;性能更加优越。芯片内置 8 KB MTP 程序存储器&#xff0c;256Byte 内部RAM&#xff0c;512Byte 外…

持绪电商:开一家抖音网店大概多久才能做起来

在数字化浪潮的推动下&#xff0c;抖音不仅是年轻人喜爱的短视频平台&#xff0c;更成为电商的新阵地。不少创业者和品牌纷纷入驻&#xff0c;希望能借力抖音的流量红利实现快速成长。但开设一家抖音网店并使其蓬勃发展&#xff0c;并非一朝一夕之事&#xff0c;它需要策略、耐…

植物大战僵尸(杂交版)最新版V2.1来袭!

【新手指导】最新版v2.1来袭 1.闪退怎么办&#xff1f; 答:窗口模式可以解决大部分问题。输入法转换成英文也可以。最后一种办法管理员运行&#xff0c;再后台可运行&#xff0c;即便不是窗口也不会闪退&#xff0c;亲测有效 2.哪里下载&#xff1f; 答&#xff1a;夸克网盘htt…

【网络编程】套接字的多种可选项

可以看出&#xff0c;套接字可选项是分层的。IPPROTOIP层可选项是IP协议相关事项IPPROTO TCP层可选项是TCP协议相关的事项&#xff0c;SOLSOCKET层是套接字相关的通用可选项 getsockopt&&setsockopt #include <sys/socket.h> int getsockopt(int sock, int lev…

呼叫中心系统的基本功能需求okcc呼叫中心pscc磐石云

呼叫中心系统的基本功能需求&#xff1a; 1、自动分配来电话务量&#xff0c;保证客户电话的最高接入率&#xff1b; 2、软电话功能&#xff1a;示忙&#xff0f;示闲&#xff0c;主叫、被叫号码显示&#xff0c;来话保持、来话转移&#xff0c;呼出&#xff0f;内部呼叫&#…