文章出處

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還可以指定超時時間


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()