今天正好碰到这个问题,也疑惑了好久。看了一圈知乎上的答案,感觉没说到根上。所以自己又好好Google了一下,终于找到了让自己信服的解释。

先说两个概念:锁池和等待池

  • 锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。
  • 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池中

Reference:java中的锁池和等待池

然后再来说notify和notifyAll的区别

  • 如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁
  • 当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争
  • 优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。

Reference:线程间协作:wait、notify、notifyAll

综上,所谓唤醒线程,另一种解释可以说是将线程由等待池移动到锁池,notifyAll调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。而notify只会唤醒一个线程。

有了这些理论基础,后面的notify可能会导致死锁,而notifyAll则不会的例子也就好解释了

wait, notify 和 notifyAll区别相关推荐

  1. notify和notifyAll区别

    notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法.两者的最大区别在于: notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状 ...

  2. Java之notify和notifyAll区别

    在Java中notify()和notifyAll()方法都是Object对象用于通知处在等待该对象的线程的方法. 两者的最大区别在于: notifyAll方法 使所有原来在该对象上等待被notify的 ...

  3. notify()和notifyAll()区别

    在同步块中调用了wait()会自动的释放该共享资源的锁,然后从运行状态中退出进入等待队列,直到再次被唤醒. 先来了解notify()的作用 该方法可以随机的唤醒等待队列中等待同一个共享资源的一个线程, ...

  4. notify() 和notifyAll()区别

    引用网上的例子,在明知到生产者 一个生产者,几个抢食者,如果通知所有的抢食者执行的操作会发生异常的时候,使用notify import java.util.ArrayList; import java ...

  5. notify()和 notifyAll()区别

    1.调用notifyAll()会唤醒所有的线程:调用notify()唤醒一个线程. 2.调用notifyAll() 会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行:如果不成功,则留 ...

  6. 用实例揭示notify()和notifyAll()的本质区别

    用实例揭示notify()和notifyAll()的本质区别 收藏 notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法.两者的最大区别在于: notifyA ...

  7. Java并发编程—notify和notifyAll有什么区别?

    原文作者:知乎用户 原文地址:https://www.zhihu.com/question/37601861/answer/145545371 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  8. Java-线程中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和区别

    Java线程中sleep().wait()和notify()和notifyAll().suspend和resume().yield().join().interrupt()的用法和区别 从操作系统的角 ...

  9. Java中notify和notifyAll的区别 - 何时以及如何使用

    Java  notify   vs notifyAll notify和notifyAll方法之间有什么区别是棘手的Java问题之一! Condition 是个什么玩意? 提几个问题,从问题中去了解去学 ...

最新文章

  1. 【物理方程】物理学中最难的方程之一,你知道多少?
  2. VIPER 和 MVVM 到底有什么区别
  3. mysql access 2017_如何把Access的数据导入到Mysql中
  4. bootstrap --- 分页
  5. 谈谈对ThreadLocal的理解?(基于jdk1.8)
  6. visual设计的界面发布到iis上显示不一样_享声 SOUNDAWARE 发布可“全民HIFI“的网播一体机 A1...
  7. 【Python】Python库之网络应用开发
  8. js 操作Listbox js 获取Listbox选择的值的代码
  9. mysql数据库基础简介_MySQL数据库之MySQL 基础之MySQL简介
  10. 【Java数据结构】二叉排序树
  11. 几何画板课件:圆周角与圆心角关系
  12. java查询时加上进度条插件,简单的jquery进度条插件LineProgressbar.js
  13. 日常折腾日记:手动配置UG二次开发环境——使用NX Open C++和Visual Studio
  14. mysql 多维度统计_SQL统计——按照各种维度
  15. 基于Python3.6和Opencv3的活动轮廓模型--CV和RSF
  16. 基于logistics回归的评分卡模型【相关理论】
  17. 腾讯云windows server搭建valheim(英灵神殿)服务器
  18. Android studio使用中问题集锦
  19. 湖南科技大学数据挖掘复习提纲
  20. [心得]C语言中实现密码输入 回显星号*

热门文章

  1. 最通俗易懂的魔方阵C语言实现
  2. 高等代数_证明_两个矩阵乘积为0,则两个矩阵的秩之和小于等于n
  3. P5738 【深基7.例4】歌唱比赛
  4. Windows实时运动控制软核(三):LOCAL高速接口测试之C++
  5. 蓝桥杯Python题目(一)
  6. 如何通过企业数字化管理降本增效?
  7. 绝大多数交互式电子白板与计算机通过链接,交互式电子白板实现了白板与计算机之间的双向交互通信与操.ppt...
  8. 【0x0001】文本生成:从零实现的char-RNN
  9. Selenium学习之显式等待中的EC模块详解
  10. gluLookAt函数