2013-08-28 105 views
7

我正在研究如何在Java中同步和易失性變量工作,我遇到了一個概念稱爲讀寫屏障。任何人都可以幫助我理解此術語的含義什麼是讀取障礙和寫入障礙同步塊

+4

你看看說明概念[1787450](http://stackoverflow.com/questions/1787450) ? – ADTC

+0

看看這個:http://stackoverflow.com/questions/1787450/how-do-i-understand-read-memory-barriers-and-volatile – Saint

+0

真的很有用的一個..謝謝你 – csk

回答

0

當您輸入代碼的同步代碼塊時,您將通過「讀取障礙物」,退出時通過「寫入障礙物」。

用於引用易失性屬性,並在線程需要更新它們的易失性屬性值時給出指示。如果其他人通過了寫屏障,他們應該在更新時通過讀屏障。

與volatile屬性的類似讀取使得線程通過讀屏障並寫入volatile屬性使您通過寫屏障,因此比同步塊的粒度要細得多。

2

A 內存屏障是代碼中的一個概念性「行」,它阻止編譯器進行某些優化,並可能會向處理器插入特殊的「同步」命令。通常,編譯器可以查看特定的方法,並查看某些指令可以在不改變代碼含義的情況下移動。舉例來說,如果你有

int x = 0, y = 0; 
x++; 
y++; 

如果編譯器想通,有一些好處,它可以代替輸出代碼

y++; 
x++; 

但是,如果xy在某些類領域,使他們可以從其他線程看到,另一個線程可能會在您的方法運行時修改這些值。

內存屏障強制編譯器重新檢查特定變量的值(在Java中,這些都是那些有volatileAtomic*類)的情況下,一些其他線程已經修改了他們,而該方法一直運行,並保持編譯器可能會意外地更改計算結果,導致重新排序。在支持多核/處理器的系統上,編譯器還會強制處理器檢查以確保某個其他處理器或硬件設備在此期間未修改該變量。 Java(自Java 5起)具有一套非常明確的規則,用於說明這個工作如何被稱爲happens-before

This FAQ有一些有用的解釋是在開發Java內存模型時編寫的。請注意,儘管內存屏障的概念是跨語言的,但大多數語言並沒有像Java那樣明確定義它們的規則。

+0

大部分好的答案,但記憶障礙不僅僅是一個編譯器的概念,也是一個硬件概念。處理器可以擁有本地緩存​​,以防止它們看到其他線程(在同一系統中的其他處理器上運行)中創建的內存更新。某些處理器指令可用於刷新這些緩存或強制通讀/直寫語義。 – davmac

+0

好點,我會編輯以反映這一點。 (最近花費太多時間在沒有緩存的處理器上......) – chrylis

0

讀寫屏障用於在JVM的最低級別實現Java內存模型的語義。

然而,該術語在Java語言規範中不存在,其僅在方面的原因發生在關係之前。特別是

  • 於揮發性可變寫入之前發生的同一個變量
  • 後續的讀取退出同步塊之前發生相同syncchronized塊

當的後續條目的發生 - 在你的程序中的兩個動作之間存在關係之前,你可以保證這兩個動作將以順序一致的順序執行(即,如果只有一個線程並且沒有不直觀的重新排序)。

深入研究JVM的實現細節對於編寫正確的多線程程序是不必要的。然而,如果你想要血淋淋的細節,JSR-133 cookbook是一個有趣的閱讀。

5

(以上問題的答案都是相當齊全),我只想用一個簡單的方案

Thread 1                Thread 2 


    |   
    |                  
    |                  | 
    |                  | 
    | Everything Thread 1             | 
    | wrote before here             | 
    |                  | 
    |                  | 
    _ _ _ _ _ _ _ _ _ _             | 
     (write barrier)   (happens before)   (read barrier) | 
    |              _ _ _ _ _ _ _ _ 
    | 
    |             is guaranteed  | 
    |             to be visible to | 
    |             Thread 2   | 
    |                  |