內存屏障和同步屏障傻傻分不清楚

程序員小迷 2024-05-19 13:05:06

一、Java 中如何保證底層操作的有序性和可見性?

1.解決方案:內存屏障。

2.有序性:內存屏障是可以插入到兩個CPU指令之間的一種指令,用來禁止處理器指令發生重排序,從而保障 有序性(確保指令的執行順序與代碼中的順序一致)。

3.可見性:爲了達到屏障的效果,內存屏障也會使處理器寫入、讀取值之前,將主內存的值寫入高速緩存,清空無效隊列,從而保障 可見性。

4.實現:

1)在Java中,內存屏障可以通過硬件或者軟件實現。

在硬件層面,CPU會提供一些專門的指令來實現內存屏障。

在軟件層面,例如使用sun.misc.Unsafe類中的loadFence和storeFence方法。

Java中的volatile和synchronized關鍵字會使用內存屏障來保證內存操作的有序性和可見性。

2)在C/C++中,編譯器指令如volatile、__sync_synchronize()以及特定處理器的內存屏障指令(如x86的mfence)可以用來實現內存屏障。

5.內存屏障能保證有序性和可見性,但不能保證原子性。

二、volatile內存屏障插入策略:

在Java內存模型(Java Memory Model即JMM)中,內存屏障是通過插入特定的JVM指令實現的。

1.在每個volatile寫操作的前面插入一個StoreStore屏障。

2.在每個volatile寫操作的後面插入一個StoreLoad屏障。

3.在每個volatile讀操作的前面插入一個LoadLoad屏障。

4.在每個volatile讀操作的後面插入一個LoadStore屏障。

三、StoreLoad 屏障:

對于這樣的僞代碼語句 Store1; StoreLoad; Load2,在 Load2 及後續所有讀取操作執行前,保證 Store1 的寫入對所有處理器可見。StoreLoad屏障的開銷是四種屏障(其它3種屏障爲LoadLoad、LoadStore、StoreStore)中最大的(沖刷緩沖器,清空無效隊列)。在大多數處理器的實現中,這個屏障是個萬能屏障,兼具其它三種內存屏障的功能。

四、synchronized關鍵字的作用

1.synchronized關鍵字能保證有序性、可見性、原子性。

2.對于 synchronized關鍵字包住的代碼區域,當線程進入到該區域讀取變量信息時,能保證讀到的是主內存中最新的值。這是因爲在同步區內對變量的寫入操作,在離開同步區時就將當前線程內的數據刷新到主內存中,而對數據的讀取也不能從緩存讀取,只能從主內存中讀取,這樣就保證了數據的讀寫有效性。

五、Android中的同步屏障

Android中分發的消息通常都是同步消息,當需要優先處理重要的異步消息時,可以設置同步屏障,使程序只能處理異步消息而不能處理同步消息。

//async爲true時Handler發送的是異步消息

public Handler(boolean async)

//async爲true時將消息設置爲異步消息

Message.setAsynchronous(boolean async)

微風不燥,陽光正好,你就像風一樣經過這裏,願你停留的片刻溫暖舒心。

我是程序員小迷(致力于C、C++、Java、Kotlin、Android、Shell、JavaScript、TypeScript、Python等編程技術的技巧經驗分享),若作品對您有幫助,請關注、分享、點贊、收藏、在看、喜歡,您的支持是我們爲您提供幫助的最大動力。

歡迎關注。助您在編程路上越走越好!

0 阅读:13

程序員小迷

簡介:致力于Android、C等編程技術的技巧經驗分享