wait : 使当前获取锁的线程挂起。可以选择wait(time,unit) 设置时间和时间单位。

notify : 使当前获取过锁并被wait过的线程由阻塞状态转为就绪状态(随机唤醒)。

notifyAll : 使当前获取过锁并被wait过的所有线程由阻塞状态转为就绪状态。

假设现在系统中有两个线程,这两个线程分别代表存款者和取钱者——现在假设系统有一种特殊的要求,系统要求存款者和取钱者不断地重复存款、取钱的动作,而且要求每当存款者将钱存入指定账户后,取钱者就立即取出该笔钱。不允许存款者连续两次存钱,也不允许取钱者连续两次取钱。

怎么实现呢? 其实可以使用wait,notify,notifyAll 来实现,notifyAll的话可以唤醒所有挂起的线程,取钱者的话我生成了多个例子,因此取钱者就用这个了。notify的话只能随机唤醒一个wait的线程,如果存钱者只有一个的话可以使用notify。但是要注意,一定要对wait过的线程才能使用notify或者notifyAll,否则没有任何意义。

看代码:

账户类

package com.zp.me.thread.wait;import lombok.Data;/*** FileName: Account* Author:  zp* Date:    2022/2022/8/30/20:40* Description:*/
@Data
public class Account {private String accountNo;private double balance;public Account() {}public Account(String accountNo, double balance) {this.accountNo = accountNo;this.balance = balance;}// 如果为true 则代表有存款,取款者可取款,反之存钱者可存钱private boolean flag = false;/**** @Description: 取钱* @Param: [money]* @return: void* @Author: zp* @Date: 2022/8/30*/public synchronized void draw(double money) {try {if (flag) {balance = balance - money;System.out.println(Thread.currentThread().getName() + "取了" + money + "元");flag = false;notifyAll();} else {wait();}} catch (InterruptedException e) {e.printStackTrace();}}/**** @Description: 存钱* @Param: [money]* @return: void* @Author: zp* @Date: 2022/8/30*/public synchronized void deposit(double money) {try {if (flag) {wait();} else {balance = balance + money;System.out.println(Thread.currentThread().getName() + "存了" + money + "元");flag = true;notify();}} catch (InterruptedException e) {e.printStackTrace();}}}

取钱线程

package com.zp.me.thread.wait;import lombok.Data;/*** FileName: DrawThread* Author:  zp* Date:    2022/2022/8/30/20:54* Description:*/
@Data
public class DrawThread extends Thread{private Account account;private double money;public DrawThread(String name,Account account, double money) {super(name);this.account = account;this.money = money;}@Overridepublic void run() {for (int i = 0; i < 10; i++) {account.draw(money);}}
}

存钱线程

package com.zp.me.thread.wait;import lombok.Data;/*** FileName: DrawThread* Author:  zp* Date:    2022/2022/8/30/20:54* Description:*/
@Data
public class DepositThread extends Thread{private Account account;private double money;public DepositThread(String name, Account account, double money) {super(name);this.account = account;this.money = money;}@Overridepublic void run() {for (int i = 0; i < 1; i++) {account.deposit(money);}}
}

测试类

package com.zp.me.thread.wait;/*** FileName: ThreadTest* Author:  zp* Date:    2022/2022/8/30/21:46* Description:*/
public class ThreadTest {public static void main(String[] args) {Account account = new Account("0000001", 0.00);new DepositThread("存钱者1",account,500).start();new DrawThread("取钱者1",account,500).start();new DrawThread("取钱者2",account,500).start();new DrawThread("取钱者3",account,500).start();}
}

结果:

Connected to the target VM, address: '127.0.0.1:61034', transport: 'socket'
存钱者1存了500.0元
取钱者3取了500.0元

可以看到,不会出现存钱者多存或者取钱者多取的情况。

wait,notify,notifyAll原理以及实际使用场景相关推荐

  1. wait,notify/notifyAll的使用及实现原理

    1.介绍 java中的wait/notify的等待唤醒机制可以实现线程间的通信,wait使当前线程进入等待,该操作会使线程阻塞,直到其它线程唤醒(调用notify.notifyAll方法)它才可继续执 ...

  2. JAVA线程间协作:wait.notify.notifyAll

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  3. java 多线程 notify_Java多线程8:wait()和notify()/notifyAll()

    轮询 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处 ...

  4. Java 多线程 4:wait() 和 notify()/notifyAll()

    轮询快速到底 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A 线程做 int 型变量 i 的累加操作,B 线程等待 i 到了 1 ...

  5. java wait notifyall_Java中的wait/notify/notifyAll

    方法 java.lang.Object public final native void wait() throws InterruptedException; public final native ...

  6. 终于搞懂了sleep/wait/notify/notifyAll

    作者:acupt,专注Java,架构师社区合伙人! sleep/wait/notify/notifyAll分别有什么作用?它们的区别是什么?wait时为什么要放在循环里而不能直接用if? 简介 首先对 ...

  7. [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?

    在 Java中,所有对象都能够被作为"监视器monitor"--指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity. 所有对象的非同步 方法都能够在任意时刻被任意线 ...

  8. sleep() wait() notify/notifyAll() 的区别

    看了一下线程这方面的知识,也结合了一些 面试的题 总结如下: 一些基础的就不说了,主要说一下这里面的几个方法,也是object的通用方法. sleep()     wait()     notify/ ...

  9. wait/notify/notifyAll在Object类中

    wait/notify/notifyAll在Object类中 因为我们在使用synchronized锁 对象锁可以是任意对象,所以wait/notify/notifyAll需要放在Object类中. ...

最新文章

  1. 利用BP神经网络教计算机识别语音特征信号(代码部分SS)
  2. SylixOS与硬件设备连接问题——硬件设备串口、网口连接问题
  3. linux命令历史详解
  4. ubuntu命令行启动浏览器_Ubuntu 秘笈之命令行下管理浏览器书签
  5. 风变的python课程怎么样_风的解释|风的意思|汉典“风”字的基本解释
  6. “3D几何与视觉技术”全球在线研讨会第四期~几何深度学习
  7. 信息安全等级保护工作概述
  8. Axis2 生成客户端
  9. java线程知识点拾遗(1)
  10. Qt学习-------常用控件
  11. 对.Net 垃圾回收的C#编程相关方面(Finalize 和Dispose(bool disposing)和 Dispose())的一些理解体会(转)...
  12. Learn Git Branching 小游戏总结
  13. Navicat提示Access violation at address ... in module ‘navicat.exe‘.Write of address ...
  14. Layui 数据表格合并单元格
  15. 我看过的世界历史纪录片和科技史、经济史、人类史笔记
  16. 快速消除PDF复制内容里的换行
  17. Unity 环境搭建
  18. Charles抓包 - 手机
  19. RX 6500 XT参数 RX6500xt怎么样
  20. dbd:oracle下载,perl DBD::oracle

热门文章

  1. 自学网络安全有什么好方法?
  2. Spring中StopWatch的使用
  3. mysql if then语句_MySQL的if,case语句使用总结
  4. 软件项目管理知识点(期末复习)
  5. 微信小程序自定义checkbox样式
  6. 传统算法与神经网络算法,神经网络算法包括哪些
  7. 谈乔布斯艺术家情怀的魅力
  8. linux中的文件锁(劝告性上锁和强制性上锁)
  9. uni-app保存图片到本地
  10. 一、求相关函数 corrcoef+协方差矩阵cov