Java的內存模型,也就是JVM所設置的內存模型。Java內存模型分為主存儲器和工作存儲器,這裡的存儲器與計算機硬件所講的不一樣。
主存儲器,就是實例位置所在的區域,所有的實例都存在主存儲器內,並且實例的字段也位於這裡。主存儲器為所有的線程所共享。
工作存儲器,它是各個線程所擁有的獨立專門的作業區。在工作存儲器中,存在有主存儲器中必要的拷貝,稱為工作拷貝。
每個線程都位於各自的工作存儲器中,每個線程都不能直接的對存儲器中字段進行引用或者賦值操作。
當線程欲引用字段的值時候,會一次將值從主存儲器拷貝到工作存儲器中,然後再引用該工作拷貝的字段。當同一個線程再次引用同一個字段的值時候,可能會引用剛才的工作拷貝,也可能會重新從主存儲器拷貝到工作存儲器。
當線程欲將值指定給字段的時候,會一次將值指定給位於工作存儲器上的工作拷貝。指定完後,工作拷貝的內容則會映射到主存儲器中。至於什麼時候映射,是都JVM決定的。當同一個線程多次對於同一個字段指定的時候,線程可能只會對工作拷貝進行指定,也有可能會每次指定後,馬上拷貝到主存儲器中。
Java中同步包括:線程的同步和內存的同步。
線程的同步指的就是利用synchronized設置一個臨界區,使得只有同時一個線程在該臨界區執行。由synchronized所指定的臨界區,來控制線程的操作。
欲進入synchronized時候,線程的工作存儲器如果有未映射到主存儲器的工作拷貝,該內容就會被強制寫入主存儲器,並且會將工作存儲器的工作拷貝全部丟棄清除掉。
欲退出synchronized時候,線程會將工作存儲器中未映射到主存儲器的工作拷貝強制寫入主存儲器中。但是並不會清除或丟棄自己的工作存儲器。
在synchronized中,不管是方法還是代碼塊,內存的同步僅僅會在線程“欲進入”與“欲退出”synchronized時候進行內存同步。如果是“在synchronized內部”或“正在synchronized外部”,不一定會有內存的同步。
對於關鍵字Volatile,它僅僅是進行內存的同步,並不會涉及線程的同步。當線程欲引用volatile字段的值,就會從主存儲器中拷貝到工作存儲器裡。對於指定給volatile字段後,工作存儲器的內容都會立刻馬上映射到主存儲器中。
記住:凡是多個線程所共享的對象,會對對象的狀態進行修改等操作的時候,一般由synchronized或volatile來保護
注意:這篇主要是對於內存模型進行了最最基本的介紹,僅供一點點參考而已。