如何解決其中的可見性和有序性導致的問題,這也就引出來了今天的主角——Java 記憶體模型,
一、什么是 Java 記憶體模型?
導致可見性的原因是快取,導致有序性的原因是編譯優化,那解決可見性、有序性最直接的辦法就是禁用快取和編譯優化,但這樣雖然解決了問題,但也導致帶來的性能優化都沒了,
因此,解決方案是:提出一套規則和方法,是程式員能在該禁用的時候禁用,不該禁用的時候不禁用,
Java 記憶體模型規范就是來解決這個問題的 —— 提供按需禁用快取和編譯優化的方法
具體來說,這些方法包括 volatile、synchronized 和 final 三個關鍵字,以及六項 Happens-Before 規則,這也正是本期的重點內容,
二、Happens-Before 規則
Q:如何理解 Happens-Before 呢?
A:前面一個操作的結果對后續操作是可見的,但不能理解為前一個操作發生在后續操作的前面,
只要最終語意是對的,編譯器怎么優化都行,
1、程式的順序性規則
這條規則是指在一個執行緒中,按照程式順序,前面的操作 Happens-Before 于后續的任意操作,
2、volatile 變數規則
這條規則是指對一個 volatile 變數的寫操作, Happens-Before 于后續對這個 volatile 變數的讀操作,
3、傳遞性
這條規則是指如果 A Happens-Before B,且 B Happens-Before C,那么 A Happens-Before C,
4、管程中鎖的規則
這條規則是指對一個鎖的解鎖 Happens-Before 于后續對這個鎖的加鎖,
5、執行緒 start() 規則
這條是關于執行緒啟動的,它是指主執行緒 A 啟動子執行緒 B 后,子執行緒 B 能夠看到主執行緒在啟動子執行緒 B 前的操作,
6、執行緒 join() 規則
它是指主執行緒 A 等待子執行緒 B 完成(主執行緒 A 通過呼叫子執行緒 B 的 join() 方法實作),當子執行緒 B 完成后(主執行緒 A 中 join() 方法回傳),主執行緒能夠看到子執行緒的操作,當然所謂的“看到”,指的是對共享變數的操作,
疑惑
Q:volatile、synchronized 和 final 能理解是提供給程式員用的,六項 Happens-Before 規則是約束誰的呢?
A:這是給程式員的保障,按照提供的規則寫,就能保證 Happens-Before 的語意,
參考文章:
Java記憶體模型以及happens-before規則
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/538823.html
標籤:其他
