併發程式設計學習筆記(七) 順序一致性

2021-09-25 10:46:14 字數 2439 閱讀 3441

順序一致性記憶體模型是乙個理論參考模型,在設計的時候,處理器的記憶體模型和程式語言的記憶體模型會以順序一致性記憶體模型作為參考。

如果乙個多執行緒程式能正確同步,這個程式將是乙個沒有資料競爭的程式。jmm對正確同步的多執行緒程式的記憶體一致性做了如下保證。

如果程式是正確同步的,程式的執行將具有順序一致性——即程式的執行結果與程式在順序一致性記憶體模型中的執行結果相同。這裡的同步是指廣義上的同步,包括對常用同步原語(synchronized,volatile和final)的正確使用。

順序一致性記憶體模型是乙個被計算機科學家理想化了的理論參考模型,它為程式設計師提供了極強的記憶體可見性保證。順序一致性記憶體模型有兩大特性。

1)乙個執行緒中的所有操作必須按照程式的順序來執行

2)(不管程式是否同步)所有執行緒都只能看到乙個單一的操作執行順序。在順序一致性記憶體模型中,每個操作都必須原子執行且立刻對所有執行緒可見。

順序一致性記憶體模型為程式設計師提供的檢視如下圖:

在概念上,順序一致性模型有乙個單一的全域性記憶體,這個記憶體通過乙個左右擺動的開關可以連線到任意乙個執行緒,同時每乙個執行緒必須按照程式的順序來執行記憶體讀/寫操作。從上面的示意圖可以看出,在任意時間點最多只能有乙個執行緒可以連線到記憶體。當多個執行緒併發執行時,圖中的開關裝置能把所有執行緒的所有記憶體讀/寫操作序列化(即在順序一致性模型中,所有操作之間具有全序關係)

假設有兩個執行緒a和b併發執行。其中a執行緒有3個操作,它們在程式中的順序是:a1 -> a2 -> a3。b執行緒也有3個操作,它們在程式中的順序是:b1 -> b2 -> b3。

假設這兩個執行緒使用監視器鎖來正確同步:a執行緒的3個操作執行後釋放監視器鎖,隨後b執行緒獲取同乙個監視器鎖。那麼程式在順序一致性模型中的執行效果如下圖:

假設兩個執行緒沒有做同步,則下面是這個未同步程式在順序一致性模型中的執行示意圖:

未同步程式在順序一致性模型中雖然整體執行順序是無序的,但所有執行緒都只能看到乙個一致的整體執行順序。以上圖為例,執行緒a和b看到的執行順序都是:b1 -> a1 -> a2 -> b2 -> a3 -> b3。之所以能得到這個保證是因為順序一致性記憶體模型中的每個操作必須立即對任意執行緒可見。

但是,在jmm中就沒有這個保證。未同步程式在jmm中不但整體的執行順序是無序的,而且所有執行緒看到的操作執行順序也可能不一致。比如,在當前執行緒把寫過的資料快取在本地記憶體中,在沒有重新整理到主記憶體之前,這個寫操作僅對當前執行緒可見。這種情況下,當前執行緒和其他執行緒看到的操作執行順序將不一致。

下面看示例**:

class

synchronizedexample

//釋放鎖

public

synchronized

void

reader()

}//釋放鎖

}

在上面的**中,假設a執行緒執行writer()方法後,b執行緒執行reader()方法。這是乙個正確同步的多執行緒程式。根據jmm規範,該程式的執行結果將與該程式在順序一致性模型中的執行結果相同。下面是該程式在兩個記憶體模型中的執行時序對比圖:

順序一致性模型中,所有操作完全按程式的順序序列執行。而在jmm中,臨界區內的**可以重排序(jmm不允許臨界區內的**跑到臨界區之外,那樣會破壞監視器的語義)。jmm會在退出臨界區和進入臨界區這兩個關鍵時間點做一些特別處理,使得執行緒在這兩個時間點具有與順序一致性模型相同的記憶體檢視。雖然執行緒a在臨界區內做了重排序,但由於監視器互斥執行的特性,這裡的執行緒b根本無法「觀察」到執行緒a在臨界區內的重排序。這種重排序既提高了執行效率,又沒有改變程式的執行結果。

從這裡可以看到,jmm在具體實現上的基本方針為:在不改變(正確同步的)程式執行結果的前提下,盡可能地為編譯器和處理器的優化開啟方便之門。

對於未同步或未正確同步的多執行緒程式,jmm只提供最小安全性:執行緒執行時讀取到的值,要麼是之前某個執行緒寫入的值,要麼是預設值(0,null,false),jmm保證執行緒讀操作讀取到的值不會無中生有(out of thin air)的冒出來。為了實現最小安全性,jvm在對上分配物件時,首先會對記憶體空間進行清零,然後才會在上面分配物件(jvm內部會同步這兩個操作)。因此,在已清零的記憶體空間分配物件時,域的預設初始化已經完成了。

在多執行緒程式中,又想要效能,又想要執行結果同順序模型一致,是不太可能的。為了保持執行結果一致,就需要做同步處理,這時候免不了要犧牲效能,因為處理器和編譯器的優化受到了禁止。

未同步程式在jmm中的執行時,整體上是無序的,其執行結果無法預知。未同步程式在兩個模型中的執行特性有如下幾個差異:

zookeeper 順序一致性

zookeeper的一致性保證在順序一致性和線性一致性之間。寫操作在zookeeper中是線性化的,換句話說,在客戶機發出請求和接收相應響應之間的某個時間點上,每次寫操作都會自動生效。這意味著zookeeper中所有客戶端執行的寫操作可以完全按照這樣一種方式進行排序,即這些寫操作的實時排序 zook...

強一致性 弱一致性 最終一致性

這種方式在es等分布式系統中也有體現,可以設定主shard提交即返回成功,或者需要replica shard提交成功再返回。提到分布式架構就一定繞不開 一致性 問題,而 一致性 其實又包含了資料一致性和事務一致性兩種情況,本文主要討論資料一致性 事務一致性指acid 複製是導致出現資料一致性問題的唯...

併發程式設計 MESI CPU快取一致性協議

mesi modified exclusive shared or invalid 也稱為伊利諾斯協議,是因為該協議由伊利諾斯州立大學提出 是一種廣泛使用的支援寫回策略的快取一致性協議。cpu中每個快取行 caceh line 使用4種狀態進行標記 使用額外的兩位 bit 表示 該快取行只被快取在該...