JAVA 并发编程之二:Object对象中的wait,notify,notifyAll 概念+作用(线程状态控制Type1)

Wesley13
• 阅读 490

wait,notify,notifyAll 是定义在Object类的实例方法,用于控制线程状态。

三个方法都必须在synchronized 同步关键字所限定的作用域中调用,否则会报错java.lang.IllegalMonitorStateException ,意思是因为没有同步,所以线程对对象锁的状态是不确定的,不能调用这些方法。

wait 表示持有对象锁的线程A准备释放对象锁权限,释放cpu资源并进入等待。
notify 表示持有对象锁的线程A准备释放对象锁权限,通知jvm唤醒某个竞争该对象锁的线程X。线程A synchronized 代码作用域结束后,线程X直接获得对象锁权限,其他竞争线程继续等待(即使线程X同步完毕,释放对象锁,其他竞争线程仍然等待,直至有新的notify ,notifyAll被调用)。
notifyAll 表示持有对象锁的线程A准备释放对象锁权限,通知jvm唤醒所有竞争该对象锁的线程,线程A synchronized 代码作用域结束后,jvm通过算法将对象锁权限指派给某个线程X,所有被唤醒的线程不再等待。线程X synchronized 代码作用域结束后,之前所有被唤醒的线程都有可能获得该对象锁权限,这个由JVM算法决定。


wait有三个重载方法,同时必须捕获非运行时异常InterruptedException。
wait() 进入等待,需要notify ,notifyAll才能唤醒
wait(long timeout) 进入等待,经过timeout 超时后,若未被唤醒,则自动唤醒
wait(timeout, nanos) 进入等待,经过timeout 超时后,若未被唤醒,则自动唤醒。相对wait(long timeout) 更加精确时间。


好了,来个通俗比喻来理解。角色分配 
线程:买家,N个线程表示N个买家 
同步块or同步方法:不同的药单。 
对象锁:取药窗口,有且只有一个,每次只服务一个买家

JAVA 并发编程之二:Object对象中的wait,notify,notifyAll 概念+作用(线程状态控制Type1)
图一,表示买家A完成取药后,医院没有叫醒其他熟睡的买家,没有睡觉的C,E买家争抢后,C获得取药机会

JAVA 并发编程之二:Object对象中的wait,notify,notifyAll 概念+作用(线程状态控制Type1)
图二,表示了notify(医院叫醒了某个熟睡的买家),跟notifyAll(医院叫醒了所有熟睡的买家)的过程。就是这么简单。

 

原文链接:

https://blog.csdn.net/cbk861110/article/details/88880498

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
2年前
Java面试
<divclass"htmledit\_views"id"content\_views"<pid"maintoc"<strong目录</strong</p<pid"Java%E5%9F%BA%E7%A1%80%EF%BC%9Atoc"style"marginleft:40px;"<ahref"Java%E5%
Wesley13 Wesley13
2年前
Java中Class对象详解
<divclass"htmledit\_views"id"content\_views"<phttps://blog.csdn.net/mcryeasy/article/details/52344729<br</p<p待优化整理总结</p<p</p<h1style"padding:0px;fontfamily:'apple
Stella981 Stella981
2年前
LocalDateTime计算时间差
<divclass"htmledit\_views"id"content\_views"<pLocalDateTime为java8的新特性之一<br</p<p<br</p<pLocalDateTime.now()获得当前时间<br</p<p</p<h5</h5<divstyle"marginleft
Wesley13 Wesley13
2年前
探索JAVA并发
\sleep/wait/notify/notifyAll分别有什么作用?它们的区别是什么?wait时为什么要放在循环里而不能直接用if?简介首先对几个相关的方法做个简单解释,Object中有几个用于线程同步的方法:wait、notify、notifyAll。publicclassObject{public
Wesley13 Wesley13
2年前
Java并发 wait()、notify()和notifyAll()
一个线程修改一个对象的值,而另一个线程则感知到了变化,然后进行相应的操作,这就是wait()、notify()和notifyAll()方法的本质。具体体现到方法上则是这样的:一个线程A调用了对象obj的wait方法进入到等待状态,而另一个线程调用了对象obj的notify()或者notifyAll()方法,线程A收到通知后从对象obj的wait方法返回,继续
Wesley13 Wesley13
2年前
Java多线程
wait()方法方法wait()的作用是使当前执行代码的线程进行等待,wait()方法是Object类的方法,该方法用来将当前线程置入“预执行队列”中,并且在wait()所在的代码行处停止执行,直到接到通知或被中断为止。注意:  在调用wait()之前,线程必须获得该对象的对象级别锁,否则会抛出illegal
Stella981 Stella981
2年前
Linux下CPU占用率高分析方法
<divclass"htmledit\_views"id"content\_views"<p一、可能有线程一直占用CPU资源</p<p1.先通过ps查看进程状态,找出进程的PID(8209)。</p<p2.jstackl8209&gt;/usr/local/work/tomcat/8209.stack导出PID
Stella981 Stella981
2年前
Python基础教程,Python入门教程(非常详细)
<divclass"htmledit\_views"id"content\_views"<p<ahref"http://c.biancheng.net/python/base/"rel"nofollow"第1章Python编程基础</a</p<p1.<ahref"http://c.biancheng.net/view/
Wesley13 Wesley13
2年前
Java 9版本之后Base64Encoder和Base64Decoder无法继续使用解决办法
<divclass"htmledit\_views"id"content\_views"<p在项目开发过程中,因为重装系统,安装了Java10版本,发现sun.misc.Base64Encoder和sun.misc.Base64Decoder无法使用。</p<p<br</p<p<strong原因:</strong</p<p查看
Stella981 Stella981
2年前
Python 线程同步变量,同步条件,列队
条件变量同步有一类线程需要满足条件之后才能够继续执行,Python提供了threading.Condition对象用于条件变量线程的支持,它除了能提供RLock()或Lock()的方法外,还提供了wait()、notify()、notifyAll()方法。lock\_conthreading.Condition(\Lock/Rlo