簡述JVM基礎(七): Java 記憶體模型與線程,jvmjava

來源:互聯網
上載者:User

簡述JVM基礎(七): Java 記憶體模型與線程,jvmjava

作者 | 井方哥

地址 | https://zhuanlan.zhihu.com/p/31582064

聲明 | 本文是 井方哥 原創,已獲授權發布,未經原作者允許請勿轉載



前言

我們通過前面的學習,已經知道了各個記憶體地區的分配等等。我們首先應該知道:

  • 服務效能重要指標:每秒交易處理數

  • 線程並發問題:阻塞、死結


本篇還解答了如下問題:

  • Java在進行執行運算時有哪些最佳化策略?

  • Java記憶體模型是怎樣的?

  • 工作記憶體和主記憶體時怎麼互動操作的?

  • Java的線程是如何?的?

  • Java的線程的狀態切換是怎樣的?


效率

1、快取

由於在進行運算時如果直接操作記憶體效率會比較低,用CPU又比較消耗資源,所以在中間加了一層快取區,作為記憶體和處理器之間的緩衝。進行運算時可以先在快取區進行讀寫操作,運算結束後將結果同步到記憶體中。

  • 優勢:解決了資源和效率的矛盾

  • 劣勢:增加了作業系統的複雜度,隨之帶來了“緩衝一致性”的問題

2、亂序執行最佳化

電腦將亂序執行的結果進行重組,並保證和順序執行的結果相同

  • 有效利用了處理器CPU

  • JVM對應有類似的指令重排序最佳化


Java 記憶體模型

  • 記憶體模型:在特定的操作協議下,對特定的記憶體或者快取進行讀寫訪問的抽象過程

  • Java記憶體模型目標:定義各個變數的訪問規則

    • 變數包括:執行個體欄位、靜態欄位、構成數組對象元素

    • 變數不包括:局部變數與方法參數(線程私人,不會被共用)

  • 主記憶體:所有變數的值都存在主記憶體當中(主要對應“Java堆”中對象執行個體資料部分)

  • 工作記憶體:背景工作執行緒直接可以操作的記憶體地區(主要對應“棧”中部分地區)

  • 線程間傳遞資料:必須要經過主記憶體

  • 工作記憶體會優先於快取和儲存寄存器,因為程式運行時主要是在工作記憶體


記憶體間互動操作

虛擬機器提供了8鐘以下8種操作,都具有原子性:

  • lock 作用於主記憶體

  • unlock 作用於主記憶體

  • read 作用於主記憶體

  • write 作用於主記憶體

  • load 作用於工作記憶體

  • use 作用於工作記憶體

  • assign 作用工作主記憶體

  • store 作用工作主記憶體

可以這麼去理解(假設在程式中我們需要將變數a賦值為2): 首先,我們進入到主記憶體,lock住a對象,接著從主記憶體中read到a對象,緊接著我們把a對象載入到工作記憶體(read和load必須順序執行),然後再工作記憶體中use了a對象的,通過a對象的指令集取到a的值,然後給a對象assign一個值,緊接著store到工作記憶體中(assign和store必須順序執行),最後把a對象write到主記憶體當中。最後最後就unlocka對象,方便其他的線程訪問,

操作原則:

  • 一個新的變數必須從主記憶體中誕生,也就是說工作記憶體中不能使用一個未初始化(load或者assign)的變數。

  • 一個變數在同一時刻只允許被一個線程lock,被同一線程多次lock之後,必須要有相同次數的unlock,變數才會被解鎖。

  • 如果該對一個變數執行了lock,則會清空這個變數在背景工作執行緒中的值

  • 對一個變數執行unlock操作之前,必須要把變數同步到主記憶體中(即執行完store和write之後)

Volatile 特點

  • 可見度:一旦被修改,所有線程都可見(普通變數需要通過主記憶體才可知)

  • 安全情境:

    • 運算結果並不依賴當前的值

    • 變數不需要與其他變數參與不變因素

  • 禁止重排序最佳化

    • 指令重排序:CPU採用了允許將多條指令不按規定的順序分開發送給各相應的電路單元處理;

    • 記憶體屏障:插入記憶體屏障指令,重排序時不能把後面的指令重排序到記憶體屏障之前的位置(實際上是保證了use或者assign操作按照代碼順序執行);

    • 尤其在代碼中進行標誌位的設定時,可能因為“機器級”的最佳化,執行順序發生了改變,加上volatile可以避免重排導致的問題;


  • 效能:讀操作與普通的差不多,寫操作由於要插入許多記憶體屏障指令來保證不進行重排序,所以會慢一些。總開銷比鎖低。

  • 操作原則:

    • read、load、use,三個動作必須連續出現;

    • 每次使用變數之前,必須從主記憶體中重新整理最新的值;


原子性、可見度、有序性

1、原子性
  • 原子性操作:read、load、use、assign、store、write

  • synchronized:lock對應於monitorenter指令,unlock對應於monitorexit指令。這兩個指令對應於synchronize關鍵字,操作對外,滿足外部同步需求。

2、可見度
  • 線程在工作記憶體操作後將資料同步到主記憶體,別的線程讀取前先從主記憶體重新整理變數值;

  • volatile:保證修改的值能立即同步到主記憶體,每次使用前需要從主記憶體重新整理。

  • synchronized:對於一個變數執行unlock之前,必須先把變數同步回主記憶體(執行store、write);

  • final:所有線程可見,如果沒有“逃逸”。

3、有序性
  • 線程內觀察,所有的操作有有序的,表現為串列

  • 一個線程去觀察另一個線程,所有的操作都是無序的,因為存在“指令重排序”現象和“工作記憶體同步到主記憶體延遲”現象

  • volatile:禁止“指令重排序”

  • synchronized:一個變數同一時刻只允許一條線程對其進行lock操作

4、先行發生原則
  • 定義:如果操作A先行發生於操作B,則操作B能夠觀察到操作A的影響;

  • 判斷依據:先行發生原則是判斷線程是否安全的依據

  • 先天原則:

    • 程式次序原則:一個線程內的操作遵循程式碼的控制流程順序

    • 管程鎖定原則:一個unlock操作先行發生於對於同一個鎖的lock之前

    • volatile原則:寫操作先行發生於後面對這個變數的讀操作

    • 線程啟動原則:Thread對象start()先行發生該線程的任何動作

    • 線程終止原則:所有操作都先行發生於該線程的終止檢測,join()方法結束、isAlive()方法檢測是否已經終止

    • 線程中斷原則:interrupt()方法先行發生於對中斷線程的檢測到中斷事件發生

    • 對象終結原則:對象初始化完成先行發生於finalize()

    • 傳遞性:操作A先於操作B,操作B先於操作C,則得出操作A先於操作C


線程實現方式

1、核心線程實現

  • 輕量級進程:通俗所說的線程;

  • 效能:

    • 使用者態和核心態來回切換,消耗效能;

    • 每個LWP都佔用一個KLT,消耗資源;

2、使用者線程實現
  • 廣義:LWP也屬於使用者線程;

  • 狹義:

    • 使用者線程完全建立在使用者空間之上,系統核心不能感知線程存在;

    • 進程和線程1:N;

  • 優點:快且低消耗

  • 缺點:線程建立、切換、調度複雜,實現困難。

3、混合實現

許多UNIX系列作業系統採用

4、Java線程實現

作業系統支援的執行緒模式不同,JVM線程的映射也不同

  • 調度方式

    • 協同式調度:一個線程幹完活通知系統切換線程

    • 搶佔式調度(Java使用):通過優先順序設定控制

  • 狀態轉換

    • 建立(NEW):尚未啟動

    • 運行(Runable):可能正在執行,也可能正在等待CPU分配時間

    • 無限等待(Wating):無限等待狀態

    • 限期等待(Timed Wating):過一定時間後自動被系統喚醒,如TheadSleep(1000)

    • 阻塞(Blocked):等待一個獨佔鎖定

    • 結束(Terminated):線程結束


小結

通過本篇的學習,終於加深了對記憶體模型、安全執行緒的理解。記憶體主要分為兩大類,一個是工作記憶體,一個主記憶體。一個線程對應一個工作記憶體,在工作記憶體內完成運算後,再把資料同步到主記憶體。由此可以得出,線程間進行通訊就必須要經過主記憶體。記憶體間的互動通過lock>read>load>use>assign>store>write>unlock這八大操作完成。其中比較特殊的是volatile關鍵字,首先他插入了記憶體屏障指令,阻止了JVM的重排序最佳化功能。同時要求在使用變數之前,必須重主記憶體中重新整理最新的值。最後學習了線程實現方式,瞭解了Java線程的New\Blocked\Running\Waiting\TimedWaiting\Terminated六種狀態的切換關係。

說明: 本系列多處摘抄《深入理解Java虛擬機器》中內容,主要精簡了本書的要點,並敘述自己對本書的理解。本人才疏學淺,文章中有不對的地方,還望批評指教。



往期

簡述JVM基礎(五):虛擬機器類載入機制



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.