對於同步的規則定義
執行緒間操作的定義
- 執行緒間操作指:一個程式執行的操作可被其他執行緒感知或被其他執行緒直接影響。
- Java記憶體模型只描述執行緒間操作,不描述執行緒內操作,執行緒內操作按照執行緒內語義執行。
執行緒間操作有:
- read操作(一般讀,即 非volatile讀)
- write操作(一般寫,即 非volatile寫)
- volatile read
- volatile write
- Lock.(鎖monitor)、Unlock
- 執行緒的第一個和最後一個操作
- 外部操作
所有執行緒間操作,都存在可見性問題,JMM需要對其進行規範
volatile關鍵字
可見性問題:讓一個執行緒對共享變數的修改,能夠及時的被其他執行緒看到。 Java記憶體模型規定:對volatile變數v的寫入,與所有其他執行緒後續對v的讀同步。
要滿足這些條件,所以volatile關鍵字就有這些功能:
- 禁止快取:
volatile變數的訪問控制符會加個
ACC_VOLATILE
——https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5
- 對volatile變數相關的指令不做重排序。
double和long的特殊處理
由於《Java語言規範》的原因,對非volatile的double、long的單次寫操作是分兩次來進行的,每次操作其中32位,這可能導致第一次寫入後,讀取的值是髒資料,第二次寫完成後,才能讀到正確值。
- 讀寫volatile修飾的long、double是原子性的。
- 商業JVM不會存在這個問題,雖然規範沒要求實現原子性,但是考慮到實際應用,大部分都實現了原子性。
- 《Java語言規範》中說道: 建議程式設計師將共享的64位值(long、double)用volatile修飾或正確同步其程式以避免可能的複雜情況。
對於同步的規則定義
-
對volatile變數v的寫入,與所有其他執行緒後續對v的讀同步。
-
對於監視器m的解鎖與所有後續操作對於m的加鎖同步。
-
對於每個屬性寫入預設值(0,false,null)與每個執行緒對其進行的操作同步。
-
啟動執行緒的操作與執行緒中的第一個操作同步。
-
執行緒T2的最後操作與執行緒T1 發現執行緒T2已經結束同步。(isAlive,join可以判斷執行緒是否終結)
-
如果執行緒T1中斷了T2,那麼執行緒T1的中斷操作與其他所有執行緒發現T2被中斷了同步。通過丟擲
InterruptedException
異常,或者呼叫Thread.interrupted
或Thread.isInterrupted
Happens-before現行發生原則
happens-before 關係用於描述兩個有衝突的動作之間的順序,如果一個action happens before 另一個action,則第一個操作被第二個操作可見,JVM需要實現如下happens-before規則:
- 某個執行緒中的每個動作都happens-before 該執行緒中該動作後面的動作。
- 某個管程上的unlock 動作 happens-before 同一個管程上後續的 lock 動作。
- 對某個 volatile 欄位的寫操作 happens-before 每個後續對該volatile欄位的讀操作。
- 在某個執行緒物件上呼叫
start()
方法 happens-before被啟動執行緒中的任意動作。 - 如果線上程t1中成功執行了
t2.join()
,則t2中的所有操作對t1可見。 - 如果某個動作 A happens-before 動作 B,且B happens-before 動作C,則有 A happens-before C。
當程式中包含兩個沒有被 happens-before 關係排序的衝突訪問時,就稱存在資料競爭。遵守了這個原則,也就意味著有些程式碼不能進行重排序,有些資料不能快取!
相關文章
- 不懂OT的列表定義操作的規則
- 定義和基本導數規則(斜率截距,指數,對數)
- [C++]變數宣告與定義的規則C++變數
- 關於laravel使用自定義驗證規則後某些規則不生效Laravel
- Spring Boot 之groups應對不同的Validation規則自定義Spring Boot
- SMART原則的定義和含義
- Redis設定Key/value的規則定義和注意事項(附工具類)Redis
- Laravel 自定義規則Laravel
- Spring MVC 基於URL的攔截和對映規則SpringMVC
- [非專業翻譯] Mapster - 基於規則的對映
- zuul 自定義路由規則Zuul路由
- SELinux: 如何讓selinux對某些命令放行,自定義selinux規則。Linux
- 識別符號定義以及命名規則(駝峰命名法)符號
- 關於mysql字符集及排序規則設定MySql排序
- win10怎麼自定義防火牆入站規則_win10設定防火牆入站規則的方法Win10防火牆
- ETL中如何自定義規則
- 『忘了再學』Shell基礎 — 11、變數定義的規則和分類變數
- 關係代數與邏輯最佳化規則 (一): 定義
- WAF開放規則定義權:專家策略+使用者自定義策略=Web安全Web
- Laravel 自定義驗證規則的問題Laravel
- Sentinel Dashboard中修改規則同步到Nacos
- web前端對檔案的引用規則Web前端
- javascript關於toFixed的計算規則JavaScript
- jQuery Validate新增自定義驗證規則jQuery
- 語義化版本 2.0.0 - 版本控制規則
- [Laravel] 自定義配置你的密碼驗證規則Laravel密碼
- 【Laravel】 自定義配置你的密碼驗證規則Laravel密碼
- 事件繫結和樣式規定的原則事件
- Laravel 自定義表單驗證-自定義驗證規則Laravel
- CMD 模組定義規範
- 基於邏輯規則的圖譜推理
- 基於準則匹配的影像對準
- HTML5 pattern自定義驗證規則HTML
- 團隊自定義 tslint & eslint 詳細規則EsLint
- 自定義Mybatis自動生成程式碼規則MyBatis
- 線上debug&gateway自定義路由規則Gateway路由
- 使用jakarta.validation自定義校驗規則
- wazuh日誌審計--定製規則