wait、notify、notifyAll方法

線程的sleep、yield、join、停止方法
wait()方法只能在同步方法中或同步塊中調用。如果調用wait()時,沒有持有適當的鎖,會拋出異常;
方法notify()、notifyAll()也要在同步方法或同步塊中調用;
1.wait()
使當前執行代碼的線程進行等待;
wait()方法執行後,當前線程釋放對象鎖(即這個資源),當前線程被阻塞,其他線程能夠拿到鎖(資源)去執行代碼;

2.notify()
喚醒等待的線程;
在notify()方法後,會釋放對象鎖,但當前線程不會馬上釋放該對象鎖,要等到執行notify()方法的線程將程序執行完,也就是退 出同步代碼塊之後纔會釋放對象鎖;並且喚醒因爲調用wait方法而被阻塞的線程;

public class Test {

    public static void main(String[] args) {

        Object object = new Object();
        new Thread(() -> {
            synchronized(object) {//鎖object對象      主線程和子線程都競爭object這個資源
                System.out.println(Thread.currentThread().getName()+"線程notify開始");
                object.notify();
                System.out.println(Thread.currentThread().getName()+"線程notify結束");
            }
        }).start();//子線程

        //主線程
        synchronized(object) {
            System.out.println(Thread.currentThread().getName()+"線程wait開始");
            try {
                object.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"線程wait結束");
        }
    }
}

結果:

在這裏插入圖片描述
從結果圖也可以看出:main線程(主線程)調用wait方法之後,主線程被阻塞,就釋放了對象鎖,使子線程Thread-0獲取到對象鎖,Thread-0(子線程)調用notify方法喚醒被阻塞的主線程後,把該子線程裏面的代碼塊執行完畢後才釋放的對象鎖,使main線程再次獲取到對象鎖,繼續執行;

3.notifyAll()
喚醒所有等待線程;
notify()是隻能喚醒一個等待線程;
但是隻有一個等待隊列時,喚醒所有線程一定會造成不該喚醒的線程又被喚醒然後再次阻塞,造成性能開銷;
其用法和notify()用法一致;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章