wait,notify,notifyAll原理以及实际使用场景
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原理以及实际使用场景相关推荐
- wait,notify/notifyAll的使用及实现原理
1.介绍 java中的wait/notify的等待唤醒机制可以实现线程间的通信,wait使当前线程进入等待,该操作会使线程阻塞,直到其它线程唤醒(调用notify.notifyAll方法)它才可继续执 ...
- JAVA线程间协作:wait.notify.notifyAll
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
- java 多线程 notify_Java多线程8:wait()和notify()/notifyAll()
轮询 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处 ...
- Java 多线程 4:wait() 和 notify()/notifyAll()
轮询快速到底 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A 线程做 int 型变量 i 的累加操作,B 线程等待 i 到了 1 ...
- java wait notifyall_Java中的wait/notify/notifyAll
方法 java.lang.Object public final native void wait() throws InterruptedException; public final native ...
- 终于搞懂了sleep/wait/notify/notifyAll
作者:acupt,专注Java,架构师社区合伙人! sleep/wait/notify/notifyAll分别有什么作用?它们的区别是什么?wait时为什么要放在循环里而不能直接用if? 简介 首先对 ...
- [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
在 Java中,所有对象都能够被作为"监视器monitor"--指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity. 所有对象的非同步 方法都能够在任意时刻被任意线 ...
- sleep() wait() notify/notifyAll() 的区别
看了一下线程这方面的知识,也结合了一些 面试的题 总结如下: 一些基础的就不说了,主要说一下这里面的几个方法,也是object的通用方法. sleep() wait() notify/ ...
- wait/notify/notifyAll在Object类中
wait/notify/notifyAll在Object类中 因为我们在使用synchronized锁 对象锁可以是任意对象,所以wait/notify/notifyAll需要放在Object类中. ...
最新文章
- 利用BP神经网络教计算机识别语音特征信号(代码部分SS)
- SylixOS与硬件设备连接问题——硬件设备串口、网口连接问题
- linux命令历史详解
- ubuntu命令行启动浏览器_Ubuntu 秘笈之命令行下管理浏览器书签
- 风变的python课程怎么样_风的解释|风的意思|汉典“风”字的基本解释
- “3D几何与视觉技术”全球在线研讨会第四期~几何深度学习
- 信息安全等级保护工作概述
- Axis2 生成客户端
- java线程知识点拾遗(1)
- Qt学习-------常用控件
- 对.Net 垃圾回收的C#编程相关方面(Finalize 和Dispose(bool disposing)和 Dispose())的一些理解体会(转)...
- Learn Git Branching 小游戏总结
- Navicat提示Access violation at address ... in module ‘navicat.exe‘.Write of address ...
- Layui 数据表格合并单元格
- 我看过的世界历史纪录片和科技史、经济史、人类史笔记
- 快速消除PDF复制内容里的换行
- Unity 环境搭建
- Charles抓包 - 手机
- RX 6500 XT参数 RX6500xt怎么样
- dbd:oracle下载,perl DBD::oracle