java多线程wait notify join
wait notify?
幾個(gè)注意點(diǎn):
wait 與 notify/notifyAll 方法必須在同步代碼塊中使用,即要先對(duì)調(diào)用對(duì)象加鎖。
當(dāng)線程執(zhí)行wait()時(shí),會(huì)把當(dāng)前的鎖釋放,然后讓出CPU,進(jìn)入等待狀態(tài)。
當(dāng)執(zhí)行notify/notifyAll方法時(shí),會(huì)喚醒一個(gè)處于等待該 對(duì)象鎖 的線程,然后繼續(xù)往下執(zhí)行,直到執(zhí)行完退出對(duì)象鎖鎖住的區(qū)域(synchronized修飾的代碼塊)后再釋放鎖。
從這里可以看出,notify/notifyAll()執(zhí)行后,并不立即釋放鎖,而是要等到執(zhí)行完臨界區(qū)中代碼后,再釋放。故,在實(shí)際編程中,我們應(yīng)該盡量在線程調(diào)用notify/notifyAll()后,立即退出臨界區(qū)。即不要在notify/notifyAll()后面再寫一些耗時(shí)的代碼
示例代碼:
public class Service {public void testMethod(Object lock) {try {synchronized (lock) {System.out.println("begin wait() ThreadName="+ Thread.currentThread().getName());lock.wait();System.out.println(" end wait() ThreadName="+ Thread.currentThread().getName());}} catch (InterruptedException e) {e.printStackTrace();}}public void synNotifyMethod(Object lock) {try {synchronized (lock) {System.out.println("begin notify() ThreadName="+ Thread.currentThread().getName() + " time="+ System.currentTimeMillis());lock.notify();Thread.sleep(5000);System.out.println(" end notify() ThreadName="+ Thread.currentThread().getName() + " time="+ System.currentTimeMillis());}} catch (InterruptedException e) {e.printStackTrace();}} }
在第3行的testMethod()中調(diào)用 wait(),在第17行的synNotifyMethod()中調(diào)用notify()
從上面的代碼可以看出,wait() 與? notify/notifyAll()都是放在同步代碼塊中才能夠執(zhí)行的。如果在執(zhí)行wait() 與? notify/notifyAll() 之前沒有獲得相應(yīng)的對(duì)象鎖,就會(huì)拋出:java.lang.IllegalMonitorStateException異常。
在第8行,當(dāng)ThreadA線程執(zhí)行l(wèi)ock.wait();這條語句時(shí),釋放獲得的對(duì)象鎖lock,并放棄CPU,進(jìn)入等待隊(duì)列。
當(dāng)另一個(gè)線程執(zhí)行第23行l(wèi)ock.notify();,會(huì)喚醒ThreadA,但是此時(shí)它并不立即釋放鎖,接下來它睡眠了5秒鐘(sleep()是不釋放鎖的,事實(shí)上sleep()也可以不在同步代碼塊中調(diào)用),直到第28行,退出synchronized修飾的臨界區(qū)時(shí),才會(huì)把鎖釋放。這時(shí),ThreadA就有機(jī)會(huì)獲得另一個(gè)線程釋放的鎖,并從等待的地方起(第24行)起開始執(zhí)行。
notify 通知的順序不能錯(cuò)
假設(shè)在線程A中執(zhí)行wait(),在線程B中執(zhí)行notify()。但如果線程B先執(zhí)行了notify()然后結(jié)束了,線程A才去執(zhí)行wait(),那此時(shí),線程A將無法被正常喚醒了(還可以通過interrupt()方法以拋出異常的方式喚醒^~^)。
?
join
thread.Join把指定的線程加入到當(dāng)前線程,可以將兩個(gè)交替執(zhí)行的線程合并為順序執(zhí)行的線程。比如在線程B中調(diào)用了線程A的Join()方法,直到線程A執(zhí)行完畢后,才會(huì)繼續(xù)執(zhí)行線程B。
如果一個(gè)線程A執(zhí)行了thread.join()語句,含義是:當(dāng)前線程A等待thread線程終止之后也從thread.join()返回?
thread.join還可以指定超時(shí)時(shí)間
總結(jié)
以上是生活随笔為你收集整理的java多线程wait notify join的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 规范打log
- 下一篇: codefores741A Arpa's