并發(fā)的核心問題:一個是互斥,即同一時刻只允許一個線程訪問共享資源;另一個是同步,即線程之間如何通信、協(xié)作。
三種管程模型:java參考的是MESA模型
Hasen 模型、Hoare 模型和 MESA 模型的一個核心區(qū)別就是當(dāng)條件滿足后,如何通知相關(guān)線程。管程要求同一時刻只允許一個線程執(zhí)行,那當(dāng)線程 T2 的操作使線程 T1 等待的條件滿足時,T1 和 T2 究竟誰可以執(zhí)行呢?
Hasen 模型里面,要求 notify() 放在代碼的最后,這樣 T2 通知完 T1 后,T2 就結(jié)束了,然后 T1 再執(zhí)行,這樣就能保證同一時刻只有一個線程執(zhí)行。
Hoare 模型里面,T2 通知完 T1 后,T2 阻塞,T1 馬上執(zhí)行;等 T1 執(zhí)行完,再喚醒 T2,也能保證同一時刻只有一個線程執(zhí)行。但是相比 Hasen 模型,T2 多了一次阻塞喚醒操作。
MESA 管程里面,T2 通知完 T1 后,T2 還是會接著執(zhí)行,T1 并不立即執(zhí)行,僅僅是從條件變量的等待隊列進到入口等待隊列里面。這樣做的好處是 notify() 不用放到代碼的最后,T2 也沒有多余的阻塞喚醒操作。但是也有個副作用,就是當(dāng) T1 再次執(zhí)行的時候,可能曾經(jīng)滿足的條件,現(xiàn)在已經(jīng)不滿足了,所以需要以循環(huán)方式檢驗條件變量。
java內(nèi)置的synchronized就是一個管程模型

入口隊列存放線程,臨界區(qū)只允許同時最多一個線程運行。
共享變量也就是要保護的資源;
條件變量是wait()/notify()的條件。
同樣,通過增加條件變量可以實現(xiàn)支持多個條件的并發(fā)編程,java提供了并發(fā)包的鎖。模型思想都是管程的思想:

08?管程:并發(fā)編程的萬能鑰匙 這一節(jié)中,老師寫的阻塞隊列就是依據(jù)這個思想,不得不說老師的代碼非常典型。
本節(jié)問題:wait() 方法,在 Hasen 模型和 Hoare 模型里面,都是沒有參數(shù)的,而在 MESA 模型里面,增加了超時參數(shù),你覺得這個參數(shù)有必要嗎?
回答:毫無疑問,肯定是必要的。增加超時的作用,在等待了這些時間后,會自動喚醒,避免一直等待。當(dāng)然,如果自己喚醒了,同樣需要檢查條件是否滿足,不滿足再次阻塞。