notify()和notifyAll()有什么区别?

先解释两个概念。

  • 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池,等待池中的线程不会去竞争该对象的锁。
  • 锁池:只有获取了对象的锁,线程才能执行对象的 synchronized 代码,对象的锁每次只有一个线程可以获得,其他线程只能在锁池中等待

区别:

notify() 方法随机唤醒对象的等待池中的一个线程,进入锁池;notifyAll() 唤醒对象的等待池中的所有线程,进入锁池。

测试代码

  1. 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 中的一个始终在等待被唤醒,程序不终止

  1. 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() 方法

  1. 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线程均可以执行完毕

  1. 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

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管理员
欢迎您,新朋友,感谢参与互动!
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
私信列表
搜索