java多線程wait notify join


wait notify 

幾個注意點:

wait 與 notify/notifyAll 方法必須在同步代碼塊中使用,即要先對調用對象加鎖。

當線程執行wait()時,會把當前的鎖釋放,然后讓出CPU,進入等待狀態。

當執行notify/notifyAll方法時,會喚醒一個處於等待該 對象鎖 的線程,然后繼續往下執行,直到執行完退出對象鎖鎖住的區域(synchronized修飾的代碼塊)后再釋放鎖。

從這里可以看出,notify/notifyAll()執行后,並不立即釋放鎖,而是要等到執行完臨界區中代碼后,再釋放。故,在實際編程中,我們應該盡量在線程調用notify/notifyAll()后,立即退出臨界區。即不要在notify/notifyAll()后面再寫一些耗時的代碼

示例代碼:

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()中調用 wait(),在第17行的synNotifyMethod()中調用notify()

從上面的代碼可以看出,wait() 與  notify/notifyAll()都是放在同步代碼塊中才能夠執行的。如果在執行wait() 與  notify/notifyAll() 之前沒有獲得相應的對象鎖,就會拋出:java.lang.IllegalMonitorStateException異常。

在第8行,當ThreadA線程執行lock.wait();這條語句時,釋放獲得的對象鎖lock,並放棄CPU,進入等待隊列。

當另一個線程執行第23行lock.notify();,會喚醒ThreadA,但是此時它並不立即釋放鎖,接下來它睡眠了5秒鍾(sleep()是不釋放鎖的,事實上sleep()也可以不在同步代碼塊中調用),直到第28行,退出synchronized修飾的臨界區時,才會把鎖釋放。這時,ThreadA就有機會獲得另一個線程釋放的鎖,並從等待的地方起(第24行)起開始執行。

notify 通知的順序不能錯

假設在線程A中執行wait(),在線程B中執行notify()。但如果線程B先執行了notify()然后結束了,線程A才去執行wait(),那此時,線程A將無法被正常喚醒了(還可以通過interrupt()方法以拋出異常的方式喚醒^~^)。

 

join

thread.Join把指定的線程加入到當前線程,可以將兩個交替執行的線程合並為順序執行的線程。比如在線程B中調用了線程A的Join()方法,直到線程A執行完畢后,才會繼續執行線程B。

如果一個線程A執行了thread.join()語句,含義是:當前線程A等待thread線程終止之后也從thread.join()返回 

thread.join還可以指定超時時間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM