Java 指令重排序與併發

2021-08-19 06:07:44 字數 735 閱讀 9886

一、

指令重排序: 編譯器或執行時環境 為了優化程式效能而採取的對指令進行重新排序執行的一種手段。

指令重排序發生在不影響語義的情況下,也就是在單執行緒下,重排序不能導致執行結果發生變化。(即遵循as-if-serial語義)

進一步解釋就是在不影響執行結果的情況下,**在jvm內的執行順序並不是嚴格按照書寫順序的,出於效能方面的考慮,jvm會對它進行重排序。

如果兩個操作訪問同乙個變數,且這兩個變數有乙個為寫操作,則這兩個操作之間是有資料依賴性的,也就是不能進行重排序。

二、例一:

int a = 1;

int b = 2;

這兩句是有可能發生指令重排序的,因為他們互不影響

例二:

int a ;

a = 1;

a = a+2;

這三句之間任意兩句都不會發生重排序,因為他們之間是具有資料依賴性的。

三、對於併發程式

public void write()

public void read()

else

}

由於指令重排序的存在,當執行緒一執行wirte,執行緒執行read時,會存在flag已經被置為true,而a還沒有被賦值的情況,此時在read裡判斷,進入分支,出現意料之外的情況。

CPU指令重排序

cpu的速度至少比記憶體快100倍,為了提公升效率,會打亂原來的執行效率,會在一條指令執行過程中 比如去記憶體讀資料,大概慢100多倍 去同時執行另一條指令 前提是兩條指令沒有依賴關係 體現在 層面 就是,寫在後面的 可能比前面的 先執行。觀察下面 測試指令重排序 public class reor...

指令重排序 as if serial

筆者認為看完一本書或剛要了解完乙個知識點 最好自己先執行一些demo 自己嘗試著去了解下各種意思 這樣知識點最終一定是你的。靠死記硬背的討論或簡單的粗暴的看下資料 腦子裡肯定還是一團漿糊。從上述的列印結果你看懂了什麼。總結如下 1 上述中下行有兩行before內容,並沒有中規中矩的先before再e...

從JVM併發看CPU記憶體指令重排序

這兩天,我拜讀了 dennis byrne 寫的一片博文memory barriers and jvm concurrency 中譯文記憶體屏障與jvm併發 文中提到 對主存的一次訪問一般花費硬體的數百次時鐘週期。處理器通過快取 caching 能夠從數量級上降低記憶體延遲的成本這些快取為了效能重新...