Java記憶體模型的曆史變遷

來源:互聯網
上載者:User

標籤:

本文通過介紹Java的新/舊記憶體模型,來展示Java技術的曆史變遷。

舊的Java記憶體模型

Java使用的是共用記憶體的並行存取模型,線上程之間共用變數。Java語言定義了執行緒模式規範,通過記憶體模型控制線程與變數的互動,從而實現Java線程之間的通訊。在JDK5之前,Java一直使用的是舊記憶體模型。1所示。變數儲存在由所有線程共用的主記憶體中,主記憶體中的變數稱為mastingcopy。每個線程都有一個工作記憶體,它儲存變數的workingcopy。舊的記憶體模型定義了若干規則,通過這些規則來保證線程何時將主記憶體中的mastingcopy傳送到線程的工作記憶體中;以及線程何時將工作記憶體中的workingcopy傳送回主記憶體。舊記憶體模型使用8個操作來定義線程可以執行的動作。

 

  • read(讀)操作:主記憶體把mastingcopy傳送到線程的工作記憶體,以供後面的load操作使用。
  • load(裝載)操作:線程將由read操作從主記憶體傳送過來的值,放入工作記憶體中。
  • use(使用)操作:線程將變數的workingcopy傳送到線程執行引擎。
  • assign(賦值)操作:線程將變數值從線程執行引擎傳送到線程的工作記憶體中。
  • store(儲存)操作:線程將變數的workingcopy傳送到主記憶體,供後面的write操作使用。
  • write(寫)操作:主記憶體將由store操作傳送過來的值,放入主記憶體中。
  • lock(鎖定)操作:線程獲得指定對象的鎖。
  • unlock(解鎖)操作:線程釋放指定對象的鎖。

 

圖1 Java舊記憶體模型

這裡的關鍵是,由於read操作是由主記憶體執行,而對應的load是由線程執行,read操作和load操作之間是鬆散耦合的。也就是說,主記憶體和線程工作記憶體之間的變數傳遞是鬆散耦合的。同樣,由於store操作是由線程執行,而對應的write是由主記憶體執行,store操作和write操作之間是鬆散耦合的。也就是說,線程工作記憶體和主記憶體之間的變數傳遞是鬆散耦合的。舊Java記憶體模型對Java實現如何執行變數的讀/寫,加鎖/解鎖,以及volatile變數的讀/寫,定義了非常嚴格的規則。這些規則非常複雜,具體詳情請參考《JVM規範》,這裡就不贅述了。舊Java記憶體模型通過這些複雜的規則,來保證多線程程式的線程之間,可以可靠地傳遞共用變數,從而保證多線程程式的正確性。

新的Java記憶體模型

從JDK5開始,Java使用新的記憶體模型,新記憶體模型完全拋棄了舊記憶體模型的主記憶體和工作記憶體的概念,也拋棄了舊記憶體模型的8個記憶體操作。也就是說,新記憶體模型完全是重新設計的。

新記憶體模型引入了一個新的概念,叫happens-before。happens-before的概念最初由LeslieLamport在其一篇影響深遠的論文(《Time,ClocksandtheOrderingofEventsinaDistributedSystem》)中提出。LeslieLamport使用happens-before來定義分布式系統中,事件之間的一個偏序關係(partialordering)。LeslieLamport在這篇論文中給出了一個分布式演算法,該演算法可以將該偏序關係擴充為某種全序關係。

JSR-133使用happens-before的概念來指定兩個操作(這裡的操作是指程式中對變數的讀/寫,對鎖的加鎖和解鎖)之間的執行順序。新記憶體模型定義了如下的happens-before規則。

 

  • 程式順序規則:一個線程中的每個操作,happensbefore於該線程中的任意後續操作。
  • 監視器鎖規則:對一個鎖的解鎖,happens-before於隨後對這個鎖的加鎖。
  • volatile變數規則:對一個volatile域的寫,happensbefore於任意後續對這個volatile域的讀。
  • 傳遞性:如果Ahappens-beforeB,且BhappensbeforeC,那麼Ahappens-beforeC。
  • start()規則:如果線程A執行操作ThreadB.start()(啟動線程B),那麼A線程的ThreadB.start()操作happensbefore於線程B中的任意操作。
  • join()規則:如果線程A執行操作ThreadB.join()並成功返回,那麼線程B中的任意操作happens-before於線程A從ThreadB.join()操作成功返回。

 

由於兩個操作可以在一個線程之內,也可以是在不同線程之間。因此JMM可以通過happens-before關係向程式員提供跨線程的記憶體可見度保證(如果A線程的寫操作a與B線程的讀操作b之間存在happens-before關係,儘管a操作和b操作在不同的線程中執行,但JMM

圖2新記憶體模型的設計

向程式員保證a操作將對b操作可見)。在新記憶體模型向程式員提供happens-before規則,程式員只需要與happens-before打交道即可,因此Java程式員的學習負擔大大降低。同時,新記憶體模型允許不會改變程式結果的重排序,這可以最大限度地放鬆對編譯器和處理器的束縛,新記憶體模型的執行效能比舊記憶體模型要好。

Java記憶體模型的曆史變遷

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.