在多核時代,如何提升CPU的性能成爲了一個永恆的話題,而這個話題的討論主要就是如何定義一個高性能的內存模型,內存模型用於定義處理器的各層緩存與共享內存的同步機制及線程和內存交互的規則。html
Java的世界也有屬於它本身的內存模型,Java內存模型,即Java Memory Model,簡稱JMM。因爲Java被定義成一種跨平臺的語言,因此在內存的描述上面也要能是跨平臺的,Java虛擬機試圖定義一種統一的內存模型,能將各類底層硬件及操做系統的內存訪問差別進行封裝,使Java程序在不一樣硬件及操做系統上都能達到相同的併發效果。它描述了程序中各個變量之間的關係,包括實例域、靜態域、數據元素及在實際計算機系統中將變量存儲到內存和從內存中取出變量的底層細節。java
爲更好理解JMM的工做機制,由圖帶入,從總體上看有幾個比較重要的主體,主存、工做內存、變量、變量副本、線程等。首先看主存與工做內存及他們的關係,主存保存了java程序的全部變量,固然這個變量不包括局部變量和方法參數,而工做內存則包含了這些變量的副本;其次是線程與工做內存的關係,每一個線程都有一個屬於本身的工做內存,不一樣線程之間的工做內存是互相不可見的,且線程對變量的操做也只能是針對本身的工做內存;最後是關於線程之間的通訊機制,因爲線程之間不可直接傳遞,假如一條線程對一個變量進行從新賦值,那麼只能經過以下途徑讓另一條線程知道,線程一將變量改變反應到主存中,線程二再從主存中讀取,這樣就基本完成了線程之間的通訊了。緩存
JMM定義了八個操做來完成工做內存與主存的通訊。假如一條線程準備對一個變量進行新的賦值操做,它可能會先用lock操做鎖住主存中的某個變量(不讓其餘線程得到此變量的鎖,直至使用unlock操做釋放該變量的鎖),接着使用read操做將變量從主存獨到工做內存,緊接着load操做將獲得的變量值放到工做內存中的變量副本,use操做則將變量值傳給線程執行引擎進行運算操做,assign操做把新的變量值從線程執行引擎中傳遞到工做內存,繼續往下,store操做則把變量值從工做內存傳送到主存中,接着write操做將獲得的值寫入主存相應的變量中,最後使用unlock操做釋放變量的鎖。多線程
Java內存模型具備三個特性:原子性、可見性和有序性。併發
JMM能夠說是Java的基礎,它的定義將直接影響JVM及java多線程實現的機制,要想深刻了解多線程併發中的相關問題現象,對Java內存模型的深刻研究是必不可少的。它的定義必須考慮下面幾個方面,其一是如何更加有效地提升線程的性能效率;其二是如何將底層物理硬件及操做系統的差別屏蔽掉提供統一的對外概念;最後是如何使它的模型既嚴謹又寬鬆,保證語義不會產生歧義和一些優化擴展。性能
====廣告時間,可直接跳過====優化
鄙人的新書《Tomcat內核設計剖析》已經在京東預售了,有須要的朋友能夠到 item.jd.com/12185360.ht… 進行預約。感謝各位朋友。操作系統
=========================線程
歡迎關注:設計