Java Memory Modle,簡稱 JMM,中文名稱 Java內存模型,它是一個抽象的概念,用來描述或者規範訪問內存變量的方式。由於各中計算機的操做系統和硬件不一樣,方式機制也可能不一樣,Java內存模型用於屏蔽(適配)各類差別,以此來達到訪問各個平臺的一致的效果。這也是Java誇平臺的重要緣由之一。java
主內存: Java內存規定了全部變量都存儲在主內存(Main Memory)中,各個線程又有本身的本地內存(工做內存),本地內存保存着主內存中部分變量。具體訪問方式以下:面試
一、原子性(Atomicity)spring
這裏的原子性如同數據庫事務中是原子性,一個或多個操做要麼全執行成功要麼全執行失敗(全不執行)。數據庫
int a = 1; a++; double b = 1.5;
Java內存模型只保證單一的操做具備原子性,好比上面的 int a = 1; 是一個單子的操做,因此具備原子性。設計模式
而 a++ 操做在底層會分爲三個操做:安全
1)、讀取a的值給臨時變量;網絡
2)、臨時變量a的值加1操做;數據結構
3)、將加操做後的值賦值給a。多線程
每一個操做都是原子的,但Java內存模型在多線程下並不能保證多操做具備總體原子性,由於它也不知道這個總體內有多少操做,用戶想要達到多操做具備總體原子性,須要對響應的代碼塊作同步(synchronous)處理,好比使用 有鎖的synchronized 或 無鎖的CAS。框架
二、可見性(Visibility)
這裏的可見性是內存可見性。
如上圖,線程1和線程2在未同步的狀況下對共享內存(主內存)中的變量進行訪問,好比兩個線程的操做都是對變量a進行加1操做。
假設線程1首先獲取主內存中變量a的值,隨後線程2又獲取了主內存變量a的值,此時它們工做內存中a的值都是1,它們各自將a的值加1操做,而後assign至工做內存,工做內存中變量a的值都是2,而後兩個線程又將值刷新到主內存,最後的結果是主內存中變量a的值是2。
雖然總體對a的值加1操做作了兩次操做,但因爲線程間的操做是互相隔離的,默認狀況下沒法感知內存變量的值在隨後的變化,也就沒法訪問內存中最新的變量值,這就是內存可行性的問題。
如何解決內存可見性的問題?
三、有序性(Ordering)
線程內的全部操做都是有序的,既程序執行的順序按照代碼的前後順序執行。好比下面的示例:
int a = 1; int b = 2; int c = a + b;
線程內程序會先執行 int a = 1; ,而後執行 int b = 2; 最後執行int c = a + b;。
文源網絡,僅供學習之用,若有侵權請聯繫刪除。我將面試題和答案都整理成了PDF文檔,還有一套學習資料,涵蓋Java虛擬機、spring框架、Java線程、數據結構、設計模式等等,但不只限於此。
關注公衆號【java圈子】獲取資料,還有優質文章每日送達。