深刻講解併發編程模型之順序一致性篇

前面兩篇文章講解過了深刻併發編程模型基本概念和重排序,尚未閱讀過前面兩篇文章的建議閱讀下:程序員


什麼是順序一致性

順序一致性,簡單理解爲:就是程序的執行順序和它編寫的順序一致編程

順序一致性模型

順序一致性內存模型是一個被計算機科學家理想化了的理論參考模型,它爲程序員提供了極強的內存可見性保證。順序一致性內存模型有兩大特性:segmentfault

  • 一個線程中的全部操做必須按照程序的順序來執行
也就是說,一個線程看到的程序的執行順序,是和它的代碼的編寫順序一致的。好比在一個線程中,代碼邏輯是先編寫A,再編寫B,最後再編寫C,那麼在一致性模型的約束下,程序的執行順序是 A -> B -> C 。是不會發生指令重排序的。(不要搞混,重排序是在JMM模型下實現的,並非一致性模型下實現。它倆的區別下文會講。)

例如,在一致性模型約束下,程序執行順序和代碼編寫順序一致。即便是A、B、C操做執行順序互不影響程序結果,也不會改變程序執行順序。
併發

  • 全部線程都只能看到一個單一的操做執行順序
在順序一致性內存模型中,每一個操做都必須原子執行且馬上對全部線程可見。也就是說,多個線程之間,無論程序是否同步,它們看到的執行順序是一致的。不可能A線程看到的程序執行順序和B線程看到的執行順序是不一致的。

例以下圖,無論程序是否執行了同步,一、2線程看到的總體程序執行順序是一致的。app

好比進行了同步,線程一、2看到的執行順序是 A -> B -> C -> D -> E -> F ,或者 D -> E -> F -> A -> B -> C 。不會出現不一致。若是未進行了同步,那麼ABC、DEF的執行順序總體是有序的,也就是說會遵照 B 或 C 不會在 A 以前執行,可是可能會在 DEF 以前執行,具體看實際的線程獲取的CPU時間片的分配。post

可是,若是未進行程序同步,因爲順序一致性模型要求線程的操做具備原子性,也就說線程的任何操做都是立刻對其它線程可見的。因此,即便代碼沒有進行線程同步,多個線程看到的代碼執行的順序也是一致。優化

順序一致性和JMM的對比

順序一致性,保證程序的執行順序一致,JMM會根據必定規則(好比遵循happens-before原則),會對程序執行指令進行重排序,達到對編譯器和處理器優化的目標。在JMM模型下,在不影響程序執行結果的前提下,編譯器、處理器會對指令進行重排序。關於重排序已經分析過,能夠閱讀這篇文章:深刻講解併發編程模型之重排序篇spa

如圖所示基於順序一致性模型和JMM模型下,在進行線程同步時程序的執行順序。在順序一致性模型下,每個線程程序執行順序已經肯定,可是在JMM模型下,每個線程在臨界區的程序執行的順序未知(虛線框起來的是臨界區代碼),由於JMM進行了指令重排。線程

順序一致性-3.png

總結

這篇文章講到這裏,已經和你們分析完了併發模型中的一致性問題。實際上,一致性模型咱們不多用,由於這樣編譯器和處理器沒法對程序作到優化,在Java中咱們使用的是能夠進行指令重排序的JMM模型。blog

還有一個緣由,前面說過,順序一致模型要求線程的每個操做都具備原子性,也就是說,讀寫都會操做主存,這樣的效率確定會比JMM模型下先對線程本地內存操做的方式要低的多。

相關文章
相關標籤/搜索