1. 程式人生 > 其它 >簡述 原子性、可見性、有序性

簡述 原子性、可見性、有序性

原子性、可見性、有序性是多執行緒中最重要的幾個點,由於多執行緒情況複雜,如何讓每個執行緒能看到正確的結果,這是非常重要的,下面我們一起來討論討論



原子性

原子性是指一個執行緒的操作是不能被其他執行緒打斷,同一時間只有一個執行緒對一個變數進行操作。在多執行緒情況下,每個執行緒的執行結果不受其他執行緒的干擾,要麼所有操作都得執行並且不會受到任何因素的干擾而中斷,要麼所有操作都不執行,多個操作是一個不可分割的整體。(使用AtomicInteger保證原子性)。

可見性

可見性是指某個執行緒修改了某一個共享變數的值,而其他執行緒是否可以看見該共享變數修改後的值。在單執行緒中肯定不會有這種問題,單執行緒讀到的肯定都是最新的值,而在多執行緒程式設計中就不一定了。

每個執行緒都有自己的工作記憶體,執行緒先把共享變數的值從主記憶體讀到工作記憶體,形成一個副本,當計算完後再把副本的值刷回主記憶體,從讀取到最後刷回主記憶體這是一個過程,當還沒刷回主記憶體的時候這時候對其他執行緒是不可見的,所以其他執行緒從主記憶體讀到的值是修改之前的舊值。

像CPU的快取優化、硬體優化、指令重排及對JVM編譯器的優化,都會出現可見性的問題。



有序性
大家都知道程式是按程式碼順序執行的,對於單執行緒來說確實是如此,但在多執行緒情況下就不是如此了。為了優化程式執行和提高CPU的處理效能,JVM和作業系統都會對指令進行重排,也就說前面的程式碼並不一定都會在後面的程式碼前面執行,即後面的程式碼可能會插到前面的程式碼之前執行,只要不影響當前執行緒的執行結果。所以,指令重排只會保證當前執行緒執行結果一致,但指令重排後勢必會影響多執行緒的執行結果。

雖然重排序優化了效能,但也是會遵守一些規則的,並不能隨便亂排序,只是重排序會影響多執行緒執行的結果。