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 RunnableImplAobj to wait on RunnableImplArun on RunnableImplAobj to wait on RunnableImplArun on RunnableImplB睡眠3秒...notify obj on RunnableImplBobj 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 RunnableImplAobj to wait on RunnableImplArun on RunnableImplAobj to wait on RunnableImplArun on RunnableImplC睡眠3秒...notifyAll obj on RunnableImplCobj continue to run on RunnableImplAobj continue to run on RunnableImplA

给TA打赏
共{{data.count}}人
人已打赏
Java

Runnable和Callable有什么区别?

2020-7-31 0:48:20

Java

乐观锁与悲观锁是什么?

2020-7-31 0:51:40

本站所发布的一切源码、模板、应用等文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权。本站内容适用于DMCA政策。若您的权利被侵害,请与我们联系处理,站长 QQ: 84087680 或 点击右侧 私信:盾给网 反馈,我们将尽快处理。
⚠️
本站所发布的一切源码、模板、应用等文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权。本站内容适用于DMCA政策
若您的权利被侵害,请与我们联系处理,站长 QQ: 84087680 或 点击右侧 私信:盾给网 反馈,我们将尽快处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索