JMM是一種規範,規定了一個線程如何和什麼時候能夠看到由其餘線程修改事後的共享變量的值以及在必須時如何同步地訪問共享變量。架構
JVM內存模型如圖Heap(堆):運行時的數據區,由垃圾回收負責,優點是能夠動態分配內存大小,生存期沒必要事先告訴編譯器,垃圾收集器會自動回收再也不使用的數據。缺點是因爲要在運行時動態分配內存因此存取速度相對較慢。線程
Stack(棧):優點是存取速度比堆快,僅次於計算機裏的寄存器,數據可共享。缺點是數據大小與生存期必須是肯定的缺乏靈活性,所以棧中主要存放一些基本類型的變量。cdn
調用棧和本地變量存放在棧上,對象存放在堆上,如上圖本地變量對對象的引用也是存放在線程棧上的。一個對象的成員變量可能會隨着對象自身存放在堆上,靜態成員變量跟隨類的定義一塊兒存放在堆上,存放在堆上的對象能夠被持有這個對象引用的線程訪問,當一個線程能夠訪問一個對象的時候也能夠訪問這個對象的成員變量。對象
**注意:**若是兩個線程同時調用同一個對象上的同一個方法,它們都訪問這個對象的成員變量可是每一個線程都擁有了這個成員變量的私有拷貝。blog
規則:內存
1.不容許Read,Load,Write,Store操做單一出現,必須按順序執行,但能夠不連續執行,即Read和Load之間,Store和Write之間是能夠插入其餘指令的。編譯器
2.不容許一個線程丟棄最近的Assign操做,也就是說變量工做內存中改變以後必須將變化同步給主內存。同步
3.一個新的變量只能在主內存中誕生,不容許在工做內存中直接使用一個未被初始化的變量。it
4.一個變量在同一時刻只容許一個線程對其執行Lock操做,可是Lock操做能夠被同一條線程執行屢次,這樣之後只有執行相同次數的Unlock變量纔會被解鎖。io
5.若一個變量執行了Lock操做,將會清空工做內存中此變量的值。在執行引擎使用這個變量以前須要從新Load
6.一個變量沒有被Lock時不容許對其執行Unlock,也不容許Unlock一個其餘線程鎖定的變量。對一個變量Unlock以前必須先把此變量同步回主內存。
Written by Autu.
2019.7.5