本篇内容介绍了“Java中怎么正确使用wait-notify方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!(1) sleep 是 Thread 方法,而 wait 是 Object 的方法 ;(2) sleep 不需要强制和 synchronized 配合使用,但 wait 需要 和 synchronized 一起用 ;(3) sleep 在睡眠的同时,不会释放对象锁的,但 wait 在等待的时候会释放对象锁 ;(4) 它们 状态 TIMED_WAITING;执行sleep()方法后的结果:在线程t1睡眠期间,主线程没有获得锁10:34:34.574 [t1] DEBUG com.example.test.Test1 – t1线程获得锁….执行wait()方法后的结果:线程t1等待20s,在线程t1等待期间,主线程获得了锁10:36:22.723 [t1] DEBUG com.example.test.Test1 – t1线程获得锁….
10:36:23.721 [main] DEBUG com.example.test.Test1 – 主线程想要获取锁….场景:有几个小孩都想进入房间内使用算盘(CPU)进行计算,老王(操作系统)就使用了一把锁(synchronized)让同一时间只有一个小孩能进入房间使用算盘,于是他们排队进入房间。(1) 小南最先获取到了锁,进入到房间内,但是由于条件不满足(没烟干不了活),小南不能继续进行计算 ,但小南如果一直占用着锁,其它人就得一直阻塞,效率太低。(2) 于是老王单开了一间休息室(调用 wait 方法),让小南到休息室(WaitSet)等着去了,这时锁释放开, 其它人可以由老王随机安排进屋(3) 直到小M将烟送来,大叫一声 [ 你的烟到了 ] (调用 notify 方法)(4) 小南于是可以离开休息室,重新进入竞争锁的队列下面我们看如何正确的实现这个场景执行结果:11:10:50.556 [小南] DEBUG com.example.test.Test2 – 有烟没?[false]
11:10:50.565 [小南] DEBUG com.example.test.Test2 – 没烟,先歇会!
11:10:52.565 [小南] DEBUG com.example.test.Test2 – 有烟没?[false]
11:10:52.565 [其他人] DEBUG com.example.test.Test2 – 可以开始干活了
11:10:52.565 [其他人] DEBUG com.example.test.Test2 – 可以开始干活了
11:10:52.565 [其他人] DEBUG com.example.test.Test2 – 可以开始干活了
11:10:52.565 [其他人] DEBUG com.example.test.Test2 – 可以开始干活了
11:10:52.565 [其他人] DEBUG com.example.test.Test2 – 可以开免费云主机域名始干活了(1) 小南线程在睡眠期间并不释放锁,因此其他线程线程也没办法获取到锁进入房间,送烟线程就没办法送烟;(2) 其它干活的线程,都要一直阻塞,效率太低 ;要解决上述的问题,需要使用wait-notify机制执行结果:11:21:36.775 [小南] DEBUG com.example.test.Test2 – 有烟没?[false]
11:21:36.780 [小南] DEBUG com.example.test.Test2 – 没烟,先歇会!
11:21:36.780 [其他人] DEBUG com.example.test.Test2 – 可以开始干活了
11:21:36.780 [其他人] DEBUG com.example.test.Test2 – 可以开始干活了
11:21:36.781 [其他人] DEBUG com.example.test.Test2 – 可以开始干活了
11:21:36.781 [其他人] DEBUG com.example.test.Test2 – 可以开始干活了
11:21:36.781 [其他人] DEBUG com.example.test.Test2 – 可以开始干活了
11:21:37.773 [小南] DEBUG com.example.test.Test2 – 有烟没?[true]
11:21:37.774 [小南] DEBUG com.example.test.Test2 – 有烟,[true],可以开始干活了解决了其他线程阻塞问题,但是如果有其他线程也在等待呢?就是说等待的线程不止小南一个,那么会不会唤醒错了呢?执行结果:送外卖的应该叫醒小女但是却把小南叫醒了11:31:50.989 [小南] DEBUG com.example.test.Test2 – 有烟没?[false]
11:31:50.994 [小南] DEBUG com.example.test.Test2 – 没烟,先歇会!
11:31:50.994 [小女] DEBUG com.example.test.Test2 – 有外卖没?[false]
11:31:50.994 [小女] DEBUG com.example.test.Test2 – 没外卖,先歇会!
11:31:51.987 [送外卖的] DEBUG com.example.test.Test2 – 外卖到了….
11:31:51.988 [小南] DEBUG com.example.test.Test2 – 有烟没?[false]
11:31:51.988 [小南] DEBUG com.example.test.Test2 – 没干成活..notify 只能随机唤醒一个 WaitSet 中的线程,这时如果有其它线程也在等待,那么就可能唤醒不了正确的线程,称之为【虚假唤醒】解决方法:改为 notifyAll执行结果:11:34:24.789 [小南] DEBUG com.example.test.Test2 – 有烟没?[false]
11:34:24.798 [小南] DEBUG com.example.test.Test2 – 没烟,先歇会!
11:34:24.798 [小女] DEBUG com.example.test.Test2 – 有外卖没?[false]
11:34:24.802 [小女] DEBUG com.example.test.Test2 – 没外卖,先歇会!
11:34:25.794 [送外卖的] DEBUG com.example.test.Test2 – 外卖到了….
11:34:25.794 [小女] DEBUG com.example.test.Test2 – 有外卖没?[true]
11:34:25.794 [小女] DEBUG com.example.test.Test2 – 有外卖,[true],可以开始干活了
11:34:25.794 [小南] DEBUG com.example.test.Test2 – 有烟没?[false]
11:34:25.795 [小南] DEBUG com.example.test.Test2 – 没干成活..从结果可以看出小女干成活,小南没有干成活。既然送烟的没到,小南应该继续等待才行,等送烟的来了再干活。用 notifyAll 仅解决某个线程的唤醒问题,但使用 if + wait 判断仅有一次机会,一旦条件不成立,就没有重新判断的机会了执行结果:当没烟的时候,小南线程继续等待,等待下一次判断有烟的时候再干活11:38:36.206 [小南] DEBUG com.example.test.Test2 – 有烟没?[false]
11:38:36.212 [小南] DEBUG com.example.test.Test2 – 没烟,先歇会!
11:38:36.212 [小女] DEBUG com.example.test.Test2 – 有外卖没?[false]
11:38:36.212 [小女] DEBUG com.example.test.Test2 – 没外卖,先歇会!
11:38:37.205 [送外卖的] DEBUG com.example.test.Test2 – 外卖到了….
11:38:37.205 [小女] DEBUG com.example.test.Test2 – 有外卖没?[true]
11:38:37.205 [小女] DEBUG com.example.test.Test2 – 有外卖,[true],可以开始干活了
11:38:37.205 [小南] DEBUG com.example.test.Test2 – 没烟,先歇会!使用wait-notify的正确姿势:调用wait()和notify()系列方法进行线程通信的要点如下:(1) 调用某个同步对象locko的wait()和notify()类型方法前,必须要取得这个锁对象的监视锁,所以wait()和notify()类型方法必须放在synchronized(locko)同步块中,如果没有获得监视锁,JVM就会报IllegalMonitorStateException异常。(2) 调用wait()方法时使用while进行条件判断,如果是在某种条件下进行等待,对条件的判断就不能使用if语句做一次性判断,而是使用while循环进行反复判断。只有这样才能在线程被唤醒后继续检查wait的条件,并在条件没有满足的情况下继续等待。“Java中怎么正确使用wait-notify方法”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注百云主机网站,小编将为大家输出更多高质量的实用文章!
这篇文章主要介绍微信小程序开发常见问题是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! Q:navigateTo 没有返回按钮。 A:Android 设计如此,需要点击物理返回键返回。 Q:关于微信小程序地图怎么获取两点…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。