Wait Set及wait、notify、notifyAll方法解读

Java中的所有对象都有一个Wait Set(又叫等待池),当某个对象执行wait方法时,线程便会暂时停止操作,进入Wait Set这个休息室,除非发生下列其中一种情况,否则线程会永远留在这个Wait Set里。
●.有其他线程以notify方法唤醒该线程
●.有其它线程以notifyAll方法唤醒该线程
●.有其它线程以interrupt方法唤醒该线程
●.wait方法时间到期(时间到了)
使用wait(等候)方法时,线程进入Wait Set。
eg:
obj.wait();
则当前线程会暂时停止执行,进入实例obj的Wait Set。
如果想执行wait()方法,线程需要获得锁(这是规则)。但是当线程进入wait set时,已经释放了此实例的锁。
Wait Set是一个虚拟的概念。它既无不是实例的字段,也不是可以获取在实例上wait set中线程列表的方法。

notify方法----从wait set拿出线程
使用notify(通知)方法时,可从wait set里抓出一个线程。eg:
obj.notify();
则从obj的wait set里面的线程中挑出一个,唤醒这个线程。被唤醒的线程便退出wait set。准备执行上一次wait后面的操作。同样,如果要执行notify()方法,

线程也需要获得锁(也是规则)。如果没有synchronized,会抛出ava.lang.IllegalMonitorStateException异常。


notify后的线程做什么?
被notify唤醒的线程并不是在notify的一瞬间重新开始执行。因为在notify的那一刻,执行notify的线程还握着锁不放,所以其他线程无法获取该实例的锁。

notify如何选择线程?
假设执行notify方法时,wait set里正在等候的线程不只一个。规格里并没有注明此时该选择哪一个线程。究竟是选择等候线程列表中的第一个、随机选择或是另以其他方式选择,则依Java处理系统而异。因此,在写程序时,程序属性最好不要写成会因所选线程而有所变动。

notifyAll依法----从wait set拿出所有线程
使用notifyAll(通知全体)方法时,会将所有在wait set里苦等的线程都拿出来。其中有一个线程幸运儿能获得实例执行。
eg:
obj.notifyAll();
则会唤醒所有留在实例obj的waitset里面的线程。此方法和前面两个方法一样,在调用时,线程要获得此实例的锁,才能调用notifyAll方法。

该用notify方法还是notifyAll方法?
notify方法和notifyAll方法两者非常相似,到底该用哪一个?老实说,这个选择有点难。选择notify的话,因为要唤醒的线程比较少,程序处理速度当然比notifyAll略胜一筹。
但选择notify时,若这部分处理得不好,可能会有程序挂掉的危险性,一般说来,选择notifyAll所写出来的程序会比选择notify可靠。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值