java的Thread線程中,爲何wait()必定要放在while循環中,而不是if條件中

在多線程的編程實踐中,wait()的使用方法以下:java

synchronized (monitor) {
    //  判斷條件謂詞是否獲得知足
    while(!locked) {
        //  等待喚醒
        monitor.wait();
    }
    //  處理其餘的業務邏輯
}


那爲何非要while判斷,而不採用if判斷呢?以下:編程

synchronized (monitor) {
    //  判斷條件謂詞是否獲得知足
    if(!locked) {
        //  等待喚醒
        monitor.wait();
    }
    //  處理其餘的業務邏輯
}



這是由於,若是採用if判斷,當線程從wait中喚醒時,那麼將直接執行處理其餘業務邏輯的代碼,但這時候可能出現另一種可能,條件謂詞已經不知足處理業務邏輯的條件了,從而出現錯誤的結果,因而有必要進行再一次判斷,以下:多線程

synchronized (monitor) {
    //  判斷條件謂詞是否獲得知足
    if(!locked) {
        //  等待喚醒
        monitor.wait();
        if(locked) {
            //  處理其餘的業務邏輯
        } else {
            //  跳轉到monitor.wait(); 
        }
    }
}

書上給予的解釋是:線程

永遠在while循環裏而不是if語句下使用wait。這樣,循環會在線程睡眠先後都檢查wait的條件,並在條件實際上並未改變的狀況下處理喚醒通知。code

結論:it

就是用if判斷的話,喚醒後線程會從wait以後的代碼開始運行,可是不會從新判斷if條件,直接繼續運行if代碼塊以後的代碼,而若是使用while的話,也會從wait以後的代碼運行,可是喚醒後會從新判斷循環條件,若是不成立再執行while代碼塊以後的代碼塊,成立的話繼續wait。class

相關文章
相關標籤/搜索