notify为什么会引发超时,notify和notifyAll的区别

每个同步对象都有对应的monitor,首先了解下monitor的内部结构。

1.monitor结构

  • Owner:指向拥有该同步对象的锁的线程,初始时为NULL
  • WaitSet(等待池):包含之前持有过锁,但是调用wait方法释放掉锁的线程
  • EntryList(锁池):包含当前正在竞争试图获取锁的线程

2.notify和notifyAll的区别

  • 线程调用了wait()方法,便会释放锁,并进入等待池(WaitSet)中,不会参与锁的竞争。
  • 调用notify()后,等待池(WaitSet)中的某个线程(只会有一个)会进入该对象的锁池(EntryList)中参与锁的竞争,若竞争成功,获得锁,竞争失败,继续留在锁池(EntryList)中等待下一次锁的竞争。
  • 调用notifyAll()后,等待池(WaitSet)中的所有线程都会进入该对象的锁池(EntryList)中参与锁的竞争。

3.notify造成超时的原因

以生产者消费者案例为例,其中缓冲区大小为1:

  1. 现在有三个线程,生产者P1, 消费者C1和C2.开始运行的时候,三个都在锁池中等待竞争,假设C1抢到锁了,C1执行时由于没有资源可以消费 调用wait()方法,释放锁并进入等待池。
  2. C2抢到了锁,开始消费,同理,C2也进入了等待池。现在锁池里面只剩下了P1。
  3. P1获得了锁,开始生产,生产完成后,P1开始调用notify()方法唤醒等待池中的C1或者C2,然后P1调用wait()方法释放锁,并进入了等待池。
  4. 假设唤醒的是C1,C1进入锁池并获得锁,消费后notify()方法唤醒了C2,C2进入锁池,C1进入等待池,现在锁池中只有C1。
  5. C1获得了锁,发现没有任何资源可以消费,wait()后释放了锁,进入了等待池,现在三个线程全都在等待池,锁池中没有任何线程。导致无限等待!

notifyAll()后,不存在只唤醒同类线程的情况,故也就不会出现上述情况。

引用

https://juejin.cn/post/6844903801363628045

notify为什么会引发超时,notify和notifyAll的区别的更多相关文章

  1. Java面试题之notify和notifyAll的区别

    锁池: 假设线程A已经拥有对象锁,线程B.C想要获取锁就会被阻塞,进入一个地方去等待锁的等待,这个地方就是该对象的锁池: 等待池: 假设线程A调用某个对象的wait方法,线程A就会释放该对象锁,同时线 ...

  2. sleep()和wait()的区别?notify()和notifyAll()的区别?start()和run()的区别?

    sleep()和wait()的区别? 这两个方法来自不同的类分别是Thread和Object sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法.wait,not ...

  3. java notify和notifyAll的区别

    首先从名字可以了解,notify是通知一个线程获取锁,notifyAll是通知所有相关的线程去竞争锁. notify不能保证获得锁的线程,真正需要锁,并且可能产生死锁. 举例1: 所有人(消费者线程) ...

  4. Java多线程Thread.yield(),thread.join(), Thread.sleep(200),Object.wait(),Object.notify(),Object.notifyAll()的区别

    Thread.yield(),在某个线程里调用Thread.yield(),会使这个线程由正在运行的running状态转变为等待cpu时间片的runable状态.join()是Thread类的一个非s ...

  5. Notify和NotifyAll的区别?

    Notify和NotifyAll都是用来对对象进行状态改变的方式,只是他们的作用域不太一样,从字面上就能看的出来,当对象被上锁之后,当其他的方法要去访问该对象中的数据,就需要该对象对其进行解锁,当然, ...

  6. sleep、wait、notify、notifyAll的区别

    Sleep 和wait 1. sleep是Thread类的静态方法,wait是Object类中定义的方法2. Thread.sleep不会导致锁行为的改变,如果当前线程是拥有锁的,那么Thread.s ...

  7. notify和notifyAll的区别

    转自:http://www.importnew.com/16453.html 如果某些线程在等待某些条件触发,那当那些条件为真时,你可以用 notify 和 notifyAll 来通知那些等待中的线程 ...

  8. 详细阐述ping命令中请求超时与无法访问的区别

    1.Request timed out 这是大家经常碰到的提示信息,很多文章中说这是对方机器置了过滤ICMP数据包,从上面工作过程来看,这是不完全 正确的,至少有下几种情况. (1) 对方已关机,或者 ...

  9. Java多线程:线程状态以及wait(), notify(), notifyAll()

    一. 线程状态类型1. 新建状态(New):新创建了一个线程对象.2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运 ...

  10. 高并发之wait notify notifyAll原理详解

    public class WaitTest { public void testWait(){ System.out.println("Start-----"); try { wa ...

随机推荐

  1. C++欧几里得算法求最大公约数和最小公倍数

    定义 最大公约数即为 Greatest Common Divisor,常缩写为 gcd. 一组整数的公约数,是指同时是这组数中每一个数的约数的数. 一组整数的最大公约数,是指所有公约数里面最大的一个. ...

  2. Python中字符串截取

    # 截取字符串时,如果位数不够,Python不会报错,而是返回空字符串 # 这是因为Python中的字符串是不可变的,所以当我们尝试访问一个不存在的索引时,Python会返回空字符串而不是报错 # 示 ...

  3. 推荐几款三维模型OBJ格式轻量化处理工具软件

    推荐几款三维模型OBJ格式轻量化处理工具软件 以下是几款常用的三维模型OBJ格式轻量化处理软件的介绍: 1.MeshLab: MeshLab是一款免费且强大的开源三维模型处理软件,支持多种文件格式,包 ...

  4. 《SQL与数据库基础》13. 视图

    目录 视图 简介 语法 检查选项 视图更新 视图作用 本文以 MySQL 为例 视图 简介 视图(View)是一种虚拟存在的表.视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的 ...

  5. 杰哥教你面试之一百问系列:java多线程

    java多线程是java面试中的高频问题,如何才能在面试中脱颖而出呢?熟读这里的一百个java多线程面试问题即可. 1. 什么是线程?什么是进程? 回答: 线程是操作系统能够进行调度的最小执行单位,它 ...

  6. 代码检视的新姿势!在IDEA中得到沉浸式Code Review新体验

    大家好,好久不见,又见面了. 在消失的这段时间里,我做了件大事,见证了儿子的出生并陪伴其一天天的成长.停止更文的200多天里,还能得到小伙伴们持续的支持,让我备受鼓励.对一个技术人员而言,分享技术观点 ...

  7. xxl-job初学转载,不断更新

    参考:https://blog.csdn.net/xhmico/article/details/122324950 官网与源码下载地址 官网:https://www.xuxueli.com/xxl-j ...

  8. 五分钟k8s入门到实战-应用配置

    背景 在前面三节中已经讲到如何将我们的应用部署到 k8s 集群并提供对外访问的能力,x现在可以满足基本的应用开发需求了. 现在我们需要更进一步,使用 k8s 提供的一些其他对象来标准化我的应用开发. ...

  9. 【RocketMQ】Dledger模式下的日志复制

    RocketMQ在开启Dledger时,使用DLedgerCommitLog,其他情况使用的是CommitLog来管理消息的存储.在Dledger模式下,消息写入时Leader节点还需要将消息转发给F ...

  10. 分布式与微服务——Iaas,Paas和Saas、单体应用和缺点、微服务概念、传统 分布式 SOA 架构与微服务架构的区别、微服务实战、什么是RPC、CAP定理和BASE理论、唯一ID生成、实现分布式

    文章目录 1-什么是Iaas,Paas和Saas 一 IaaS基础设施服务 二 paas平台即服务 三saas软件即服务 四 总结 2-单体应用和缺点 一 单体应用 二 单体应用的缺陷 3-微服务概念 ...