1. 程式人生 > >wait()和notify()

wait()和notify()

package concurrent._wait_notify;

public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        ThreadA a = new ThreadA("A");
        synchronized (a){
            System.out.println("開始主執行緒睡眠3000ms");
            Thread.sleep(3000);
            System.out.println("
啟動a"); a.start(); System.out.println("開始主執行緒睡眠5000ms"); Thread.sleep(5000); System.out.println("主執行緒wait"); a.wait(); System.out.println("主執行緒剛從阻塞隊列出來,馬上結束了"); } } } class ThreadA extends Thread{ public ThreadA(String name){ super(name); } @Override
public void run() { System.out.println("嘗試獲得this鎖"); synchronized (this){ System.out.println("獲得了this鎖,準備notify"); this.notify(); System.out.println("notify()成功"); } } }

結果:

開始主執行緒睡眠3000ms
啟動a
開始主執行緒睡眠5000ms
嘗試獲得this鎖
主執行緒wait
獲得了this鎖,準備notify
notify()成功
主執行緒馬上結束了

 

 

修改程式碼:

package concurrent._wait_notify;

public class Demo2 {
    public static void main(String[] args) throws InterruptedException {
        Object obj = new Object();

        ThreadB b1 = new ThreadB("b1",obj);
        ThreadB b2 = new ThreadB("b2",obj);
        ThreadB b3 = new ThreadB("b3",obj);

        b1.start();
        b2.start();
        b3.start();

        Thread.sleep(1000);
        synchronized (obj){
            obj.notifyAll();
        }
    }


}

class ThreadB extends  Thread{
    private Object obj;
    public ThreadB(String name,Object obj){
        super(name);
        this.obj = obj;
    }

    @Override
    public void run() {
        String threadName = this.getName();
        System.out.println(threadName +"嘗試獲得obj鎖");
        synchronized (obj){
            try {
                System.out.println(threadName+"獲得了obj鎖,進入wait");
                obj.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(threadName+"從wait出來了");
        }
    }
}

結果:

b2嘗試獲得obj鎖
b2獲得了obj鎖,進入wait
b3嘗試獲得obj鎖
b3獲得了obj鎖,進入wait
b1嘗試獲得obj鎖
b1獲得了obj鎖,進入wait
b1從wait出來了
b3從wait出來了
b2從wait出來了

再次修改程式碼將Thread.sleep(1000)註釋掉

 

結果顯示:

b1嘗試獲得obj鎖
b1獲得了obj鎖,進入wait
b2嘗試獲得obj鎖
b3嘗試獲得obj鎖
Main函式獲得了鎖,進行notifyAll操作
b1從wait出來了
b3獲得了obj鎖,進入wait
b2獲得了obj鎖,進入wait

這個結果就是,獲得鎖的順序是,b1,main,b2,b3。(列印順序,不能反映cpu獲得鎖的順序,只能說明列印的順序)

當main函式執行完成notifyAll()之後,b1從阻塞隊列出來,結束執行,這時候b2,b3再次進入阻塞狀態,但是卻沒有別的程序將他們喚醒,就會一直阻塞。

 

notify操作,實際上是釋放基於某個鎖上面的wait的執行緒,是根據鎖來釋放的。

wait操作是讓當前在cpu執行的執行緒,基於某個鎖上wait,便於基於某個鎖上喚醒。

 

文章參考部落格:

http://www.cnblogs.com/xingele0917/p/3979494.html