Java內存模型

對於Java內存模型總結起來就是:
1. 爲何定義Java內存模型?現代計算機體系大部是採用的對稱多處理器的體系架構。每一個處理器均有獨立的寄存器組和緩存,多個處理器可同時執行同一進程中的不一樣線程,這裏稱爲處理器的亂序執行。在Java中,不一樣的線程可能訪問同一個共享或共享變量。若是任由編譯器或處理器對這些訪問進行優化的話,頗有可能出現沒法想象的問題,這裏稱爲編譯器的重排序。除了處理器的亂序執行、編譯器的重排序,還有內存系統的重排序。所以Java語言規範引入了Java內存模型,經過定義多項規則對編譯器和處理器進行限制,主要是針對可見性和有序性。
2. 三個基本原則:原子性、可見性、有序性。
3. Java內存模型涉及的幾個關鍵詞:鎖、volatile字段、final修飾符與對象的安全發佈。其中:第一是鎖,鎖操做是具有happens-before關係的,解鎖操做happens-before以後對同一把鎖的加鎖操做。實際上,在解鎖的時候,JVM須要強制刷新緩存,使得當前線程所修改的內存對其餘線程可見。第二是volatile字段,volatile字段能夠當作是一種不保證原子性的同步但保證可見性的特性,其性能每每是優於鎖操做的。可是,頻繁地訪問 volatile字段也會出現由於不斷地強制刷新緩存而影響程序的性能的問題。第三是final修飾符,final修飾的實例字段則是涉及到新建對象的發佈問題。當一個對象包含final修飾的實例字段時,其餘線程可以看到已經初始化的final實例字段,這是安全的。
4. Happens-Before的7個規則:
(1).程序次序規則:在一個線程內,按照程序代碼順序,書寫在前面的操做先行發生於書寫在後面的操做。準確地說,應該是控制流順序而不是程序代碼順序,由於要考慮分支、循環等結構。
(2).管程鎖定規則:一個unlock操做先行發生於後面對同一個鎖的lock操做。這裏必須強調的是同一個鎖,而"後面"是指時間上的前後順序。
(3).volatile變量規則:對一個volatile變量的寫操做先行發生於後面對這個變量的讀操做,這裏的"後面"一樣是指時間上的前後順序。
(4).線程啓動規則:Thread對象的start()方法先行發生於此線程的每個動做。
(5).線程終止規則:線程中的全部操做都先行發生於對此線程的終止檢測,咱們能夠經過Thread.join()方法結束、Thread.isAlive()的返回值等手段檢測到線程已經終止執行。
(6).線程中斷規則:對線程interrupt()方法的調用先行發生於被中斷線程的代碼檢測到中斷事件的發生,能夠經過Thread.interrupted()方法檢測到是否有中斷髮生。
(7).對象終結規則:一個對象的初始化完成(構造函數執行結束)先行發生於它的finalize()方法的開始。
5. Happens-Before的1個特性:傳遞性。
6. Java內存模型底層怎麼實現的?主要是經過內存屏障(memory barrier)禁止重排序的,即時編譯器根據具體的底層體系架構,將這些內存屏障替換成具體的 CPU 指令。對於編譯器而言,內存屏障將限制它所能作的重排序優化。而對於處理器而言,內存屏障將會致使緩存的刷新操做。好比,對於volatile,編譯器將在volatile字段的讀寫操做先後各插入一些內存屏障。緩存

相關文章
相關標籤/搜索