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

235 篇文章 62 订阅
订阅专栏
121 篇文章 67 订阅
订阅专栏
30 篇文章 2 订阅
订阅专栏

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面试题与答案】整理推荐

 

面试官上来就问我多线程&并发的问题,还好我早有准备
超越无限_
03-16 622
问题一:notify()和notifyAll()有什么区别notify可能会导致死锁,而notifyAll则不会 任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码 使用notifyall,可以唤醒 所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个。 wait() 应配合while循环使用,不应使用if,务必在wait()调用前后都检查条件,如果不满足,必须调用 notify()唤醒另外的线程来处理,自己继续wait()直至条
Java notifynotifyAll的区别和相同
09-01
本文主要介绍Java notifynotifyAll的知识,这里整理详细的资料来说明notify 和NotifAll的区别,有需要的小伙伴可以参考下
JAVA --- notifynotifyAll 有什么区别
最新发布
xycxycooo的博客
08-01 385
notify:随机唤醒一个正在等待该对象锁的线程,适用于只需要一个线程继续执行的场景。notifyAll:唤醒所有正在等待该对象锁的线程,适用于需要所有线程都尝试继续执行的场景。
如何在 Java 中正确使用 wait, notifynotifyAll
极北三少
08-05 2744
wait, notifynotifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。 在 Java 中可以用 wait、notifynotifyAll 来实现线程间的通信。。举个例子,如果你的Java程序中有两个线程——即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓冲区中有内
notify()和 notifyAll()有什么区别
m0_68464502的博客
06-05 3180
因此,在多线程编程中,如果需要唤醒所有等待该对象的线程,则可以使用notifyAll()方法;notifyAll()方法则会唤醒等待队列中的所有线程,并使它们竞争获取锁,这样可以使所有线程都有机会获取锁并进入运行状态,从而避免了一些线程一直处于等待状态。notify()方法只会唤醒等待队列中的一个线程,并使其与其他线程竞争获取锁,这可能会导致某些线程无法被唤醒或者一直处于等待状态。notify()方法只会随机唤醒等待队列中的一个线程,而notifyAll()方法则会唤醒等待队列中的所有线程。
notify()和notifyAll()有什么区别
qq_33240556的博客
12-28 1111
都是Java中用于唤醒等待在特定对象上的线程的方法,它们都用于处理多线程编程中的同步问题。然而,如果你需要唤醒所有等待的线程,并且担心多个线程同时尝试进入同步代码块或方法的风险,那么使用。取决于你的具体需求。如果你知道需要唤醒的特定线程,并且知道其他线程不会同时尝试进入同步代码块或方法,那么使用。可能是一个更好的选择。
notify()和notifyAll()有什么区别
admin0811的博客
09-25 1733
notify是对notifyAll()的一个优化,但它有很精确的应用场景,并且要求正确使用,不然可能导致死锁,正确的场景应该是WaitSet中等待的是相同的条件,唤醒任一个都能正确处理接下来的事项,如果唤醒的线程无法正确处理,务必确保继续notify()下一个线程,并且自身需要重新回到WaitSet中。wait()应配合while循环使用,不应该使用if,务必在wait()调用前后都检查条件,如果不满足,必须调用notify()唤醒另外的线程来处理,自己继续wait()直至条件满足在往下执行。
notify()与notifyAll()的区别
qq_34614587的博客
03-04 336
在使用notify()与使用notifyAll()时不必纠结:notify()方法将等待队列中的一个等待线程从等待队列中移步到同步队列中,而notifyAll()方法则将等待队列中所有的线程全部地道同步队列,被移动的线程状态由waiting变为blocked;因此一般情况下,因尽量使用notify(),以免将等待队列中的线程全部移动到阻塞队列中,过多消耗系统资源。近期总结一些有用的小知识点,比较琐...
基于Java多线程notifynotifyall的区别分析
09-05
本文将深入探讨`notify()`和`notifyAll()`的区别及其在实际使用中的注意事项。 `wait()`方法使当前线程进入等待状态,并释放它所持有的对象锁。只有在持有该对象锁的情况下,线程才能调用`wait()`。当其他线程调用...
java notifynotifyAll的对比
08-31
总结来说,`notify`和`notifyAll`的主要区别在于唤醒线程的数量和选择策略。`notify`只唤醒一个线程,但不保证其是合适的线程;而`notifyAll`唤醒所有等待的线程,增加竞争,通常用于确保至少有一个线程可以继续执行...
wait、notifynotifyAll本质是在干什么?
自救 唯有自强
02-25 200
为什么他们可以使线程等待?为什么可以让线程间相互通信?通过什么通信? 其实是基于java的对象头。 每一个java对象都有对象头,而wait,notifynotifyAll,就是基于对象头中的锁状态标识。 这其实也是为什么使用wait,notifynotifyAll方法的对象,需要先使用synchronized同步的原因。 使用举例: public class MainGLock { static class IRunable implements Runnable{ @Sne
Java 同步方式 wait和notify/notifyall
06-24
在Java中,`wait()`, `notify()`, 和 `notifyAll()` 是Java Object类的三个方法,它们在实现线程间通信和协作时扮演着关键角色。这些方法主要用于解决线程等待和唤醒的问题,是基于Java Monitor(监视器)模型的。 ...
notify()和notifyAll()的本质区别
中国华的博客
03-13 7519
notify()和notifyAll()的本质区别 notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。两者的最大区别在于: notifyAll使所有原来在该对象上等待被notify的所有线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。 notify则文明得多,它只是选择一个wait状态线程进行通知,并使它获得该对象...
notifynotifyAll有什么区别
weixin_34259232的博客
11-28 186
先说两个概念:锁池和等待池 锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。等待池:假设一个线程A调用了某个对象的wait()方法,线程...
notifynotifyAll的区别
有才而性缓,定属大才。有智而气和,斯为大智。
09-02 6123
6、notifynotifyAll的区别 notify方法只唤醒一个等待(对象的)线程并使该线程开始执行。所以如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统对多线程管理的实现。notifyAll 会唤醒所有等待(对象的)线程,尽管哪一个线程将会第一个处理取决于操作系统的实现。如果当前情况下有多个线程需要被唤醒,推荐使用notifyAll 方法。比如在生...
notify()和 notifyAll()有什么区别
ITzhanghao的博客
08-30 1712
notify()和notifyAll()的区别? notify(): 唤醒一个处于等待状态的线程, 注意的是在调用此方法的时候, 并不能确切的唤醒某一个等待状态的线程, 而是由JVM确定唤醒哪个线程,而且不是按优先级。 notifyAll(): 唤醒所有处入等待状态的线程; 并可以理解为把他们排进一个队列; 只不过只有头部的线程获得了锁,才能运行; 注意!!并不是给所有唤醒线程一个对象的锁,而...
Notifynotifyall的区别
macSun_jh的博客
03-15 705
Notifynotifyall的区别notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。 notify则文明得多他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句...
042_notify() 和 notifyAll() 有什么区别
qq_39932502的博客
04-23 446
如果线程调用了对象的 wait() 方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。 当有线程调用了对象的 notifyAll() 方法 (唤醒所有 wait 线程) 或 notify() 方法 (只随机唤醒一个 wait 线程) ,被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了 notify() 后只有一个线程会由等待池进入锁池...
notifynotifyAll的一段代码分析
qi20088的专栏
04-08 428
根据网友的意见,修改版如下: 当你Google”notify()和notifyAll()的区别”时,会有大片的结果弹出来,(这里先把jdk的javadoc文档那一段撇开不说),所有这些搜索结果归结为等待的线程被唤醒的数量:notify()是唤醒一个, 而notifyall()是唤醒全部.那他们的真正区别是什么呢? 让我们来看看个生产者/消费者的案例(假设生产者/消费者这个类中有两个方法
写文章

热门文章

  • jdk、jre各版本下载 87068
  • @Autowired 的作用是什么? 78206
  • == 和 equals 的区别 64741
  • Queue 中 add() 和 offer() 区别 62070
  • 什么是 java 序列化?什么情况下需要序列化? 55727

最新评论

  • java 程序中怎么保证多线程的运行安全?

    vd_vd: 只有我觉得答得不错吗表情包

  • BIO、NIO、AIO 有什么区别?

    啦啦啦hh: NIO的含义是不是写错了

  • 线程池包含哪些状态?

    我不是小白啊: [code=plain] SHUTDOWN 状态下,任务数为 0, 其他所有任务已终止,线程池会变为 TIDYING 状态,会执行 terminated() 方法。线程池中的 terminated() 方法是空实现,可以重写该方法进行相应的处理。 线程池在 SHUTDOWN 状态,任务队列为空且执行中任务为空,线程池就会由 SHUTDOWN 转变为 TIDYING 状态。 [/code] 这俩感觉意思一样呢,都是搜友任务都执行完了。

  • Excel 文件的扩展名 .xls 与 .xlsx 的区别

    CSDN-Ada助手: 多亏了你这篇博客, 解决了问题: https://ask.csdn.net/questions/8039802, 请多输出高质量博客, 帮助更多的人

  • Java 面试题

    飞羽疾驰: 可以的,我看的另一篇,面试时90%以上的题目都在下边这个文章里:https://knife.blog.csdn.net/article/details/121219272

大家在看

  • 三石峰物联网云平台,你值得了解
  • Qt C++设计模式->组合模式
  • 摆脱困境并在 Android 手机上取回删除照片的所有解决方案 776
  • MySQL篇(锁机制 基本介绍、全局锁\表级锁\行锁、悲观锁\乐观锁)
  • shopify主题开发中给产品页设置多个模板

最新文章

  • 梳理一下分布式系统的问题
  • 项目中如何用 Spring 和 Spring MVC 框架的?
  • Spring 框架用到了哪些设计模式?
2021年84篇
2020年395篇
2019年311篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家品质玻璃钢卡通雕塑图片昆明卡通玻璃钢雕塑厂家乐从玻璃钢人物雕塑业界口碑好平顶山肖像玻璃钢雕塑汕尾玻璃钢景观雕塑材料宁波玻璃钢景观雕塑批发上海室内商场美陈市场报价吉林省玻璃钢雕塑设计玻璃钢花盆怎么浇水泌阳玻璃钢雕塑设计不锈钢水景玻璃钢卡通雕塑设计台州公园玻璃钢雕塑定制兴宁玻璃钢浮雕人物山水雕塑河北节庆商场美陈市场价鹤壁商场美陈绿植墙深圳中庭商场美陈供应2022年商场美陈青岛玻璃钢雕塑摆件采购南京玻璃钢雕塑之家西安玻璃钢雕塑文化内涵山东玻璃钢造型雕塑玻璃钢雕塑英语泰州玻璃钢仿铜雕塑定做玻璃钢兵马俑雕塑厂家潮州玻璃钢动物雕塑出厂价格翠屏玻璃钢花盆花器湖南玻璃钢牛动物雕塑制作工厂广州玻璃钢雕塑灯玻璃钢雕塑机器浙江工业玻璃钢雕塑摆件香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化