●.有其他线程以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可靠。