notify和notifyAll的区别,notify死锁问题
具体讲解参照博客区别
下面补充一个例子,来说明,使用notify会产生死锁,但是使用notifyAll不会。
原题为lleetcode 1195
大体意思是:四个线程,调用同一个对象的四个不同方法,然后实现线程的同步。
在这里使用了synchornized和state来实现
这个题目。
下面分析一种情况说明notify会产生死锁,而notifyAll会。
修改完state = 0后,使用notify激活了应该执行state = 3的线程A。
然后,线程state = 0, 调用了wait方法,锁死了自己。
此时,锁队列上,挂了四个线程,虽然此时的锁已经释放了,但是没有外部的干预,四个线程都没有回到竞争队列上面的时候。
这就出现了有锁,但是无法执行的状态。
但是这并不是操作系统意义上面的死锁。因为不满足死锁的四个状态。
package leetcode;import java.util.function.IntConsumer;/*
*
* 这里是一个错误的同步
* */
public class FizzBuzz3 extends FizzBuzz{// 使用synchornize + state的方式来实现private int state = 0; // 0 : 数字, 1 :fizz, 2:buzz, 3private Object obj = new Object();private int n;public FizzBuzz3(int n) {super(n);this.n = n;}// printFizz.run() outputs "fizz".public void fizz(Runnable printFizz) throws InterruptedException {for (int i = 3; i <= n; i += 3) {if (i % 5 == 0) continue;synchronized (obj) {while (state != 1) {obj.wait();}printFizz.run();state = 0;obj.notifyAll();}}}// printBuzz.run() outputs "buzz".public void buzz(Runnable printBuzz) throws InterruptedException {for (int i = 5; i <= n; i += 5) {if (i % 3 == 0) continue; // 如果不行,就不该状态,否则最后一个可能输出不了synchronized (obj) {while (state != 2) {obj.wait();}printBuzz.run();state = 0;obj.notifyAll(); // 可能会死锁,如果都wait就死锁了。}}}// printFizzBuzz.run() outputs "fizzbuzz".public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {for (int i = 15; i <= n; i += 15) { // 只要等于3,就可以直接输出了synchronized (obj) {while (state != 3) {obj.wait();}
// System.out.println("\nstate = " + state + " i = " + i);printFizzBuzz.run();state = 0; // 只有输出才有资格改,否则自己也能竞争obj.notifyAll();}}}// printNumber.accept(x) outputs "x", where x is an integer.public void number(IntConsumer printNumber) throws InterruptedException {for (int i = 1; i <= n; i++) {synchronized (obj) {while (state != 0) {obj.wait();}if (i % 3 != 0 && i % 5 != 0) {printNumber.accept(i);} else {if (i % 3 == 0 && i % 5 == 0) {state = 3;} else if (i % 5 == 0) {state = 2;} else state = 1;}
// System.out.println(" state = " + state);obj.notifyAll();}}}public static void main(String[] args) throws Exception{String[] className = {"leetcode.FizzBuzz3", "20"};FuzzBuzzMain.main(className);}
}
notify和notifyAll的区别,notify死锁问题相关推荐
- notify 和 notifyAll的区别
6.notify 和 notifyAll的区别 notify方法只唤醒一个等待(对象的)线程并使该线程开始执行.所以如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统 ...
- Java中notify和notifyAll的区别 - 何时以及如何使用
Java notify vs notifyAll notify和notifyAll方法之间有什么区别是棘手的Java问题之一! Condition 是个什么玩意? 提几个问题,从问题中去了解去学 ...
- Notify与notifyall的区别
Notify与notifyall的区别 notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争. notify则文 ...
- Java中notify() 和 notifyAll()的区别
等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池,等待池中的线程不会去竞争该对象的锁. 锁池:只有获取了对象的锁,线程才能执行对象的 sync ...
- notify()和notifyAll()的区别
1.notify()只能唤醒一个wait()线程,然而notifyAll()可以唤醒多个wait()线程: 2.两个都必须在synchronized中使用,过程不释放锁: 3.当每个线程都有特定锁的时 ...
- java notify什么意思_Java notify和notifyAll的区别和相同
经常在往上逛,关于在java中notify和notifyAll,经常有人有以下的说法: notify只会通知一个在等待的对象,而notifyAll会通知所有在等待的对象,并且所有对象都会继续运行 并且 ...
- Java多线程——notify()与notifyAll()的区别
notify(): 唤醒在此对象监视器上等待的单个线程.如果所有线程都在此对象上等待,则会选择唤醒其中一个线程.选择是任意性的,并在对实现做出决定时发生.线程通过调用其中一个 wait 方法,在对象的 ...
- notify()和 notifyAll()有什么区别
notify()和notifyAll()的区别? notify(): 唤醒一个处于等待状态的线程, 注意的是在调用此方法的时候, 并不能确切的唤醒某一个等待状态的线程, 而是由JVM确定唤醒哪个线程, ...
- Java并发编程—notify和notifyAll有什么区别?
原文作者:知乎用户 原文地址:https://www.zhihu.com/question/37601861/answer/145545371 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...
最新文章
- VR眼镜,怎样才算性感?
- ubuntu下交叉编译环境构建
- 第17课:RDD案例(join、cogroup等实战)
- MySQL(介绍,安装,密码操作,权限表)
- 基于SSH框架社区智能化管理系统答辩PPT模板
- ZOJ1002-Fire Net(深度优先搜索)
- 爬取百度迁徙2021年春运迁徙数据(仅省份级别)
- 2013台式计算机,显卡天梯图 2013最新台式机显卡天梯图
- 子div在父div垂直居中的最好方法
- Mysql之to_base64编码from_base64解密和AES_ENCRYPT加密AES_DECRYPT解密
- cesium entity使用
- 智慧家安监控系统——用Java + html、css、js实现
- 战略项目——科龙空调中高层干部培训记
- 关于微信公众号页面获取code进行微信授权登录
- C# 流不可读 解决办法
- 每周分享第 13 期:周刊为什么只谈技术?
- 三大集成学习之万金油 - Catboost
- Python return函数返回值详解
- vue3.0 + element-plus + 上传图片到七牛云
- linux发送短信的脚本,编写脚本实现服务器登录短信告警