《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(13)--- 线程安全接口和双检查加锁优化...
4.3線程安全接口(Thread-Safe Interface)
1.問題
? ? ? 多線程組件通常包括多個可被公共訪問的接口方法以及可以改變組件狀態的私有方法。為了避免出現競爭條件,可以使用一個組件內部的鎖對訪問其狀態的接口方法調用串行化。盡管當每個方法都自包容的時候,這種設計方法能很好地工作。但組件方法可能會相互調用完成計算任務。如果是這樣,在多線程組件中有以下幾個強制條件尚未解決,它們使用了錯誤的組件間方法調用的設計方法:
? ? ? 1)應該使線程安全組件避免“自死鎖”。當一個組件方法在該組件中獲得一個非遞歸鎖,然后調用試圖獲得同一個鎖的另一個組件方法時,會發生自死鎖。
? ? ? 2)為了避免出現對組件狀態的競爭條件等情況,應該使線程安全組件具有最小的加鎖開銷。如果為避免上面介紹的自死鎖問題而選擇一個遞歸組件鎖,由于組件間方法調用多次獲得和釋放鎖,而會產生不必要的開銷。
?
2.解決方案
? ? ? 按照以下兩個約定將處理組件間方法調用的所有組件初始化:
? ? ? 1)接口方法檢查。所有接口方法(如C++公有方法)應該只獲得/釋放組件鎖,在組件的“邊緣”進行同步檢查。獲得一個鎖后,接口方法立即轉發給一個實現方法,后者執行實際的方法功能。實現方法返回后,接口在將控制返回給調用者之前釋放該鎖。
? ? ? 2)實現方法信任。只有被接口方法調用,實現方法(如C++的私有或保護方法)才能完成它們的任務。因此它們相信只有在獲得鎖后才會調用它們,它們本身不應該獲得或釋放鎖。實現方法也不應該“向上”調用接口方法,因為接口要獲得鎖。?
?
3.實現
1)確定接口和相應的實現方法。接口方法定義組件的公共API,為每個接口方法對應地定義一個實現方法。
2)對接口和實現方法進行編程。
?
4.結論
優點:
? ? ? 1)提高了健壯性。由于使用組件間方法調用,該模式可以避免自死鎖。
? ? ? 2)改善了性能。該模式確保在必要時才獲得或釋放鎖。
? ? ? 3)簡化了軟件。將加鎖和功能特性問題分開,可以使加鎖和功能特性得到簡化。
?
不足:
? ? ? 1)增加間接的和額外的方法。
? ? ? 2)潛在的死鎖。
? ? ? 3)潛在的誤用。
? ? ? 4)潛在的開銷。
?
?
4.4雙檢查加鎖優化(double-checked locking optimization)
1.問題
? ? ? 串行化加鎖方法對于只要求執行一次初始化的對象或組件是不合適的,例如Singleton中的臨界區代碼在其初始化階段必須執行一次。但是對Singleton的每個方法調用都要獲取和釋放互斥鎖,從而過多地增加了開銷,為避免這些開銷,并發應用的程序員可能轉而使用全局變量而不是單件模式。不過這種解決方案有兩個缺點:
? ? ? ·可移植性不好。因為通常沒有指定在不同文件中定義的全局對象被構造的順序。
? ? ? ·資源的浪費。因為即使不使用全局變量,也要產生全局變量。
?
2.解決方案?
? ? 引入一個標志,表示在獲得一個保證臨界區的鎖之前確定是否需要執行該臨界區。如果不需要執行該代碼,就跳過該臨界區,從而避免了不必要的加鎖開鎖。在臨界區內增加相同的標志檢測,表示進入臨界區后是否需要初始化資源,從而避免了資源被多次初始化。
?
3.實現
1)確定要僅執行一次的臨界區。該臨界區進行的操作(如初始化邏輯)在程序中僅執行一次。
2)實現加鎖邏輯。加鎖邏輯對只執行一次的臨界區代碼的訪問串行化。
3)實現首次進入(first-time-in)標志。該標志表示臨界區是否被執行過。
?
4.結論
優點:
? ? ? 1)使加鎖開銷最小。
? ? ? 2)防止競爭條件。
?
不足:
? ? ? 1)非原子指針或集成賦值語義。
? ? ? 2)多處理器緩存的連貫性。
? ? ? 3)額外的互斥使用。?
轉載于:https://www.cnblogs.com/pennant/archive/2012/09/24/2698956.html
總結
以上是生活随笔為你收集整理的《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(13)--- 线程安全接口和双检查加锁优化...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MYSQL AB复制原理
- 下一篇: setBackgroundResourc