亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java的wait(), notify()和notifyAll()使用心得

2019-11-26 16:00:50
字體:
來源:轉載
供稿:網友
wait(),notify()和notifyAll()都是java.lang.Object的方法:
wait(): Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
notify(): Wakes up a single thread that is waiting on this object's monitor.
notifyAll(): Wakes up all threads that are waiting on this object's monitor.
這三個方法,都是Java語言提供的實現線程間阻塞(Blocking)和控制進程內調度(inter-process communication)的底層機制。在解釋如何使用前,先說明一下兩點:
1. 正如Java內任何對象都能成為鎖(Lock)一樣,任何對象也都能成為條件隊列(Condition queue)。而這個對象里的wait(), notify()和notifyAll()則是這個條件隊列的固有(intrinsic)的方法。
2. 一個對象的固有鎖和它的固有條件隊列是相關的,為了調用對象X內條件隊列的方法,你必須獲得對象X的鎖。這是因為等待狀態條件的機制和保證狀態連續性的機制是緊密的結合在一起的。
(An object's intrinsic lock and its intrinsic condition queue are related: in order to call any of the condition queue methods on object X, you must hold the lock on X. This is because the mechanism for waiting for state-based conditions is necessarily tightly bound to the mechanism fo preserving state consistency)
根據上述兩點,在調用wait(), notify()或notifyAll()的時候,必須先獲得鎖,且狀態變量須由該鎖保護,而固有鎖對象與固有條件隊列對象又是同一個對象。也就是說,要在某個對象上執行wait,notify,先必須鎖定該對象,而對應的狀態變量也是由該對象鎖保護的。
知道怎么使用后,我們來問下面的問題:
1. 執行wait, notify時,不獲得鎖會如何?
請看代碼:
復制代碼 代碼如下:

public static void main(String[] args) throws InterruptedException {
        Object obj = new Object();
        obj.wait();
        obj.notifyAll();
}

執行以上代碼,會拋出java.lang.IllegalMonitorStateException的異常。
2. 執行wait, notify時,不獲得該對象的鎖會如何?
請看代碼:
復制代碼 代碼如下:

public static void main(String[] args) throws InterruptedException {
        Object obj = new Object();
        Object lock = new Object();
        synchronized (lock) {
            obj.wait();
            obj.notifyAll();
        }
    }

執行代碼,同樣會拋出java.lang.IllegalMonitorStateException的異常。
3. 為什么在執行wait, notify時,必須獲得該對象的鎖?
這是因為,如果沒有鎖,wait和notify有可能會產生競態條件(Race Condition)。考慮以下生產者和消費者的情景:
1.1生產者檢查條件(如緩存滿了)-> 1.2生產者必須等待
2.1消費者消費了一個單位的緩存 -> 2.2重新設置了條件(如緩存沒滿) -> 2.3調用notifyAll()喚醒生產者
我們希望的順序是: 1.1->1.2->2.1->2.2->2.3
但在多線程情況下,順序有可能是 1.1->2.1->2.2->2.3->1.2。也就是說,在生產者還沒wait之前,消費者就已經notifyAll了,這樣的話,生產者會一直等下去。
所以,要解決這個問題,必須在wait和notifyAll的時候,獲得該對象的鎖,以保證同步。
請看以下利用wait,notify實現的一個生產者、一個消費者和一個單位的緩存的簡單模型:
復制代碼 代碼如下:

public class QueueBuffer {
    int n;
    boolean valueSet = false;
    synchronized int get() {
        if (!valueSet)
            try {
                wait();
            } catch (InterruptedException e) {
                System.out.println("InterruptedException caught");
            }
        System.out.println("Got: " + n);
        valueSet = false;
        notify();
        return n;
    }
    synchronized void put(int n) {
        if (valueSet)
            try {
                wait();
            } catch (InterruptedException e) {
                System.out.println("InterruptedException caught");
            }
        this.n = n;
        valueSet = true;
        System.out.println("Put: " + n);
        notify();
    }
}

復制代碼 代碼如下:

public class Producer implements Runnable {
    private QueueBuffer q;
    Producer(QueueBuffer q) {
        this.q = q;
        new Thread(this, "Producer").start();
    }
    public void run() {
        int i = 0;
        while (true) {
            q.put(i++);
        }
    }
}

復制代碼 代碼如下:

public class Consumer implements Runnable {
    private QueueBuffer q;
    Consumer(QueueBuffer q) {
        this.q = q;
        new Thread(this, "Consumer").start();
    }
    public void run() {
        while (true) {
            q.get();
        }
    }
}

復制代碼 代碼如下:

public class Main {
    public static void main(String[] args) {
        QueueBuffer q = new QueueBuffer();
        new Producer(q);
        new Consumer(q);
        System.out.println("Press Control-C to stop.");
    }
}

所以,JVM通過在執行的時候拋出IllegalMonitorStateException的異常,來確保wait, notify時,獲得了對象的鎖,從而消除隱藏的Race Condition。
最后來看看一道題:寫一個多線程程序,交替輸出1,2,1,2,1,2......
利用wait, notify解決:
復制代碼 代碼如下:

public class OutputThread implements Runnable {
    private int num;
    private Object lock;
    public OutputThread(int num, Object lock) {
        super();
        this.num = num;
        this.lock = lock;
    }
    public void run() {
        try {
            while(true){
                synchronized(lock){
                    lock.notifyAll();
                    lock.wait();
                    System.out.println(num);
                }
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static void main(String[] args){
        final Object lock = new Object();
        Thread thread1 = new Thread(new OutputThread(1,lock));
        Thread thread2 = new Thread(new OutputThread(2, lock));
        thread1.start();
        thread2.start();
    }
}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩av在线影院| 国产成人精品av| 国产精品久久久久久久app| 久热精品视频在线观看| 亚洲白虎美女被爆操| 视频在线观看一区二区| 日韩综合视频在线观看| 不卡毛片在线看| 欧美日韩国产精品专区| 欧美疯狂性受xxxxx另类| 亚洲免费av电影| 国产精品视频白浆免费视频| 国产精品久久久久久久久粉嫩av| 人人做人人澡人人爽欧美| 亚洲一区二区三| 欧美一级片在线播放| 欧美日韩成人在线播放| 国产精品18久久久久久首页狼| 亚洲欧美精品中文字幕在线| 91九色国产社区在线观看| 中文字幕成人精品久久不卡| 亚洲欧美精品一区二区| 欧美黑人性视频| 欧美日韩第一视频| 中文字幕亚洲综合久久筱田步美| 欧美日韩在线另类| 法国裸体一区二区| 久久久久北条麻妃免费看| 海角国产乱辈乱精品视频| 亚洲国产精久久久久久| 九九九热精品免费视频观看网站| 国产精品露脸av在线| 国产欧美久久久久久| 91免费综合在线| 精品毛片网大全| 欧美日韩国产成人| 色与欲影视天天看综合网| 国产一区二区三区网站| 91精品国产91| 中文字幕亚洲一区| 欧美日韩在线免费观看| 色哟哟亚洲精品一区二区| 成人性生交xxxxx网站| 国产精品视频男人的天堂| 国产精品av免费在线观看| 国内精品久久久| 国产一区二区日韩精品欧美精品| 成人一区二区电影| 久久久成人av| 影音先锋日韩有码| 午夜精品久久久久久久久久久久久| 亚洲综合精品一区二区| 日韩欧美中文在线| 中文字幕不卡在线视频极品| 成人免费视频网址| 欧美视频二区36p| 国产91在线播放精品91| 欧美精品免费在线| 国内揄拍国内精品少妇国语| 欧美亚洲另类制服自拍| 亚洲男人的天堂网站| 成人亚洲欧美一区二区三区| 久久亚洲国产成人| 国产视频精品va久久久久久| 日本国产高清不卡| 精品国产自在精品国产浪潮| 中文字幕日韩精品在线| 日韩中文字幕不卡视频| 日韩国产中文字幕| 亚洲视频在线免费看| 国产精品久久久久久久久久尿| 欧美久久精品午夜青青大伊人| 亚洲欧美国产精品va在线观看| 在线日韩av观看| 91精品国产高清久久久久久| 国产亚洲欧美日韩精品| 亚洲女在线观看| 精品国产一区二区三区久久| 不卡中文字幕av| 日本一区二区不卡| 亚洲国产日韩精品在线| 欧美国产日韩一区二区| 精品国产老师黑色丝袜高跟鞋| 最近2019中文免费高清视频观看www99| 国产欧美韩国高清| 国产91av在线| 精品成人乱色一区二区| 日韩中文字幕在线视频播放| 日本精品久久久久久久| 欧美日本黄视频| 欧美日韩国产一中文字不卡| 欧美一区二区三区……| 亚洲欧美日本另类| 91视频国产高清| 久久久国产精品视频| 亚洲精品免费网站| 97精品一区二区视频在线观看| 久久天天躁夜夜躁狠狠躁2022| xxx一区二区| 国产精品高清免费在线观看| 一区二区日韩精品| 欧美成年人在线观看| 亚洲激情视频网| 国产主播欧美精品| 欧美电影电视剧在线观看| 丁香五六月婷婷久久激情| 日韩欧美成人区| 91精品国产乱码久久久久久蜜臀| 日韩小视频在线观看| 热久久免费视频精品| 国产日韩欧美电影在线观看| 亚洲www在线观看| 久久久久久久久爱| 欧美美最猛性xxxxxx| www国产亚洲精品久久网站| 夜夜嗨av色综合久久久综合网| 亚洲无限av看| 日韩精品在线免费| 爽爽爽爽爽爽爽成人免费观看| 亚洲自拍小视频免费观看| 日日噜噜噜夜夜爽亚洲精品| 91久久久久久久| 精品久久香蕉国产线看观看亚洲| 91tv亚洲精品香蕉国产一区7ujn| 色妞久久福利网| 亚洲精品自拍视频| 国产精品成av人在线视午夜片| 91久久中文字幕| 亚洲美女性生活视频| 日韩经典一区二区三区| 日韩在线视频线视频免费网站| 亚洲国产欧美精品| 国产日韩专区在线| 色哟哟网站入口亚洲精品| 亚洲精品国产精品久久清纯直播| 久久精品视频中文字幕| 国产视频自拍一区| 欧美视频一二三| 97超视频免费观看| 午夜精品福利电影| 尤物yw午夜国产精品视频明星| 国产精品色悠悠| 欧美日韩免费在线观看| 久久久久久亚洲精品中文字幕| 亚洲国产精品久久| 亚洲精品久久久久久久久久久久久| 国产精品吊钟奶在线| 亚洲成色www8888| 欧美午夜精品伦理| 精品网站999www| 另类图片亚洲另类| 精品国产一区二区三区久久久| 欧美日韩免费网站| 中文字幕国产亚洲2019| 国产精品视频网| 亚洲精品99999| 国产精品美女av| 亚洲第一区中文字幕| 亚洲第一区在线观看| 91亚洲精品在线观看| 欧洲精品毛片网站| 亚洲电影第1页| 色偷偷偷综合中文字幕;dd| 国产一区二区三区在线观看网站|