notify() 和 notifyAll() 有什么区别?「建议收藏」
什么 建议 收藏 区别 notify notifyAll
2023-06-13 09:13:45 时间
notify() 和 notifyAll() 有什么区别?
先解释两个概念。
- 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池,等待池中的线程不会去竞争该对象的锁。
- 锁池:只有获取了对象的锁,线程才能执行对象的 synchronized 代码,对象的锁每次只有一个线程可以获得,其他线程只能在锁池中等待
区别:
notify() 方法随机唤醒对象的等待池中的一个线程,进入锁池;notifyAll() 唤醒对象的等待池中的所有线程,进入锁池。
测试代码
public class TestNotifyNotifyAll {
private static Object obj = new Object();
public static void main(String[] args) {
//测试 RunnableImplA wait()
Thread t1 = new Thread(new RunnableImplA(obj));
Thread t2 = new Thread(new RunnableImplA(obj));
t1.start();
t2.start();
//RunnableImplB notify()
Thread t3 = new Thread(new RunnableImplB(obj));
t3.start();
// //RunnableImplC notifyAll()
// Thread t4 = new Thread(new RunnableImplC(obj));
// t4.start();
}
}
class RunnableImplA implements Runnable {
private Object obj;
public RunnableImplA(Object obj) {
this.obj = obj;
}
public void run() {
System.out.println("run on RunnableImplA");
synchronized (obj) {
System.out.println("obj to wait on RunnableImplA");
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("obj continue to run on RunnableImplA");
}
}
}
class RunnableImplB implements Runnable {
private Object obj;
public RunnableImplB(Object obj) {
this.obj = obj;
}
public void run() {
System.out.println("run on RunnableImplB");
System.out.println("睡眠3秒...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj) {
System.out.println("notify obj on RunnableImplB");
obj.notify();
}
}
}
class RunnableImplC implements Runnable {
private Object obj;
public RunnableImplC(Object obj) {
this.obj = obj;
}
public void run() {
System.out.println("run on RunnableImplC");
System.out.println("睡眠3秒...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj) {
System.out.println("notifyAll obj on RunnableImplC");
obj.notifyAll();
}
}
}
结果:仅调用一次 obj.notify(),线程 t1 或 t2 中的一个始终在等待被唤醒,程序不终止
run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplB
睡眠3秒...
notify obj on RunnableImplB
obj continue to run on RunnableImplA
把 t3 注掉,启动 t4 线程。调用 obj.notifyAll() 方法
public class TestNotifyNotifyAll {
private static Object obj = new Object();
public static void main(String[] args) {
//测试 RunnableImplA wait()
Thread t1 = new Thread(new RunnableImplA(obj));
Thread t2 = new Thread(new RunnableImplA(obj));
t1.start();
t2.start();
// //RunnableImplB notify()
// Thread t3 = new Thread(new RunnableImplB(obj));
// t3.start();
//RunnableImplC notifyAll()
Thread t4 = new Thread(new RunnableImplC(obj));
t4.start();
}
}
结果:t1、t2线程均可以执行完毕
run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplC
睡眠3秒...
notifyAll obj on RunnableImplC
obj continue to run on RunnableImplA
obj continue to run on RunnableImplA
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
相关文章
- Java项目毕业设计:基于springboot+vue的电影视频网站系统「建议收藏」
- 贴片电阻丝印是什么意思「建议收藏」
- 示波器表笔旁边的夹子是什么_示波器的基础操作,初学者必看教程「建议收藏」
- 什么是大数据开发?「建议收藏」
- 前端,什么是跨域,及跨域常见的解决方案(简讲)「建议收藏」
- 什么是跨域访问「建议收藏」
- 测试显卡矿卡用什么软件,3分钟看懂:AMD二手矿卡简明鉴别、检测教程,从此脱坑不求人…「建议收藏」
- 什么是面向对象?「建议收藏」
- 什么是java常量「建议收藏」
- java和基岩版区别_我的世界基岩版与Java版有什么区别?「建议收藏」
- Java是什么软件-详细解答Java到底是什么「建议收藏」
- Java和Python有什么区别,初学者学Java还是Python?「建议收藏」
- java.util.scanner sc_Java的Scanner sc=new Scanner(System.in)是什么意思「建议收藏」
- 什么是MVC三层架构?「建议收藏」
- Ant是什么?「建议收藏」
- 第一章:什么是数据化运营「建议收藏」
- 相机的光圈大小有什么区别「建议收藏」
- 认识 Iconfont 以及什么是 .eot、.woff、.ttf、.svg「建议收藏」
- 单片机中P1=0x01什么意思「建议收藏」
- ER图是什么?「建议收藏」
- 精益六西格玛与零售管理是什么关系