java多线程并行执行命令_深入理解Java多线程与并发框(第④篇)——重排序、屏障指令、as-if-serial规则...

# 一、重排序
前篇文章已經講了Java內存模型和與其三個特性:原子性、可見性、有序性。但事實上,為了提升程序的執行性能,編譯器 和 處理器 常常會對程序指令序列進行 重排序。
重排序分為以下幾種:
- 編譯器優化重排序
- 處理器重排序
- 指令級并行重排序
- 內存系統重排序
# 二、屏障指令
fence
內存屏障(Memory Barrier,或稱為內存柵欄,Memory Fence)是一種CPU指令,用于控制特定條件下的重排序和內存可見性問題。Java編譯器也會根據內存屏障的規則在一定程度地禁止重排序。
# 三、as-if-serial 語句
>重排序也不能毫無規則,否則語義就變得不可讀, as-if-serial語句 給重排序戴上緊箍咒,起到約束作用。
**as-if-serial語句**規定重排序要滿足以下兩個規則:
- 在單線程環境下不能改變程序執行的結果;
- 存在數據依賴關系代碼(指令)片段的不允許重排序。
比如下面的代碼:
```
int a = 1;
// ①
int b = 2;
// ②
int c = a + b;
// 依賴于 ① 和 ②
return c;
```
可能會被優化成:
```
int b = 2;
// ②
int a = 1;
// ①
int c = a + b;
// 依賴于 ① 和 ②
return c;
```
上述的重排序既沒有改變單線程下程序運行的結果,又沒有對存在依賴關系的指令進行重排序。
# 四、happens-before 規則
產生的背景是為了確保多線程操作下具有內存可見性。
如果一個操作執行的結果需要對另一個操作可見,那么這兩個操作之間必須要存在happens-before關系。換句話說,操作1 happens-before 操作2,那么操作1的結果是對操作2可見的。
這里提到的兩個操作既可以是在一個線程之內,也可以是在不同線程之間。
**規則**:
1. 程序順序規則:一個線程中的每個操作,happens-before 于該線程中的任意后續操作
2. 監視器鎖規則:對一個鎖的解鎖,happens-before 于隨后對這個鎖的加鎖
3. volatile變量規則:對一個volatile域的寫,happens-before 于任意后續對這個volatile域的讀
4. 傳遞性:如果A happens-before B,且B happens-before C,那么A happens-before C
5. start規則:如果線程A執行操作ThreadB.start()(啟動線程B),那么A線程的ThreadB.start()操作happens-before于線程B中的任意操作
6. join規則:如果線程A執行操作ThreadB.join()并成功返回,那么線程B中的任意操作happens-before于線程A從ThreadB.join()操作成功返回。
# 總結:
as-if-serial 語句保證單線程環境下不能改變程序執行的結果,happens-before 規則保證多線程環境下不能改變程序執行的結果。
來自 “ ITPUB博客 ” ,鏈接:http://blog.itpub.net/69964492/viewspace-2682230/,如需轉載,請注明出處,否則將追究法律責任。
總結
以上是生活随笔為你收集整理的java多线程并行执行命令_深入理解Java多线程与并发框(第④篇)——重排序、屏障指令、as-if-serial规则...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php pdo mysql 乱码,php
- 下一篇: Java编号姓名元宝数密码,通过my E