自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

循序漸進(jìn) 理解什么是Java內(nèi)存模型

開發(fā) 后端
本文從硬件可能出現(xiàn)的問題引出計算機(jī)內(nèi)存模型解決方案,進(jìn)而提取出多線程并發(fā)問題,最后再引出Java內(nèi)存模型。

近期筆者在閱讀《深入理解Java虛擬機(jī):JVM高級特性與最佳實(shí)現(xiàn)(第3版)》,書中提到關(guān)于Java內(nèi)存模型的知識點(diǎn),但是看完之后還是感覺有些模糊,便查閱一些其他相關(guān)資料。本文是筆者經(jīng)過對知識理解和整理后的一個總結(jié),希望能夠幫助朋友們對Java內(nèi)存模型有更加清晰的認(rèn)識,對于文章內(nèi)容有其他想法或意見建議等,歡迎提出共同討論共同進(jìn)步。下面將從以下三點(diǎn)展開討論:

  • 內(nèi)存模型的由來
  • 內(nèi)存模型的定義
  • Java內(nèi)存模型及實(shí)現(xiàn)

內(nèi)存模型的由來

1. 計算機(jī)在執(zhí)行程序的時候每條指令都是由CPU來執(zhí)行的。而CPU在執(zhí)行的時候?yàn)榱双@取數(shù)據(jù),所以難免與主存打交道。

[[315407]]

2. 隨著CPU技術(shù)的發(fā)展其執(zhí)行越來越高速度,越來也快,同時因內(nèi)存技術(shù)發(fā)展比較緩慢,性能沒有太大的變化,所以導(dǎo)致出現(xiàn)CPU每次操作內(nèi)存都需要耗費(fèi)一定的等待時間。

循序漸進(jìn)--理解什么是Java內(nèi)存模型

3. 為在保證CPU技術(shù)發(fā)展同時優(yōu)化解決這一問題,人們后來想出來了一個方案,就是在CPU和內(nèi)存之間增加高速緩沖存儲器(Cache)。

高速緩沖存儲器是存在于主存與CPU之間的一級存儲器, 由靜態(tài)存儲芯片(SRAM)組成,容量比較小但速度比主存高得多, 接近于CPU的速度。在計算機(jī)存儲系統(tǒng)的層次結(jié)構(gòu)中,是介于中央處理器和主存儲器之間的高速小容量存儲器。它和主存儲器一起構(gòu)成一級的存儲器。高速緩沖存儲器和主存儲器之間信息的調(diào)度和傳送是由硬件自動進(jìn)行的。

循序漸進(jìn)--理解什么是Java內(nèi)存模型

因?yàn)镃ache速度接近于CPU的速度且CPU每次操作主存前都會先訪問Cache,所以通過增加Cache后當(dāng)便達(dá)到了優(yōu)化的效果。

4. 隨著CPU的升級,一層緩存慢慢地?zé)o法滿足要求,因此逐漸地衍生出多級緩存。每一級緩存中所儲存的全部數(shù)據(jù)都是下一級緩存的一部分。而CPU讀取數(shù)據(jù)也演變?yōu)椋寒?dāng)CPU要讀取一個數(shù)據(jù)時,首先從一級緩存中查找,如果沒有找到再從二級緩存中查找,如果還是沒有就從下一級緩存查直到訪問內(nèi)存。如下圖所示

循序漸進(jìn)--理解什么是Java內(nèi)存模型

5. 單核CPU只含有一套L1,L2,L3緩存;如果CPU含有多個核心,即多核CPU,則每個核心都含有一套L1(甚至和L2)緩存,而共享L3(或者和L2)緩存,下圖是一個單CPU雙核得緩存結(jié)構(gòu)圖:

循序漸進(jìn)--理解什么是Java內(nèi)存模型

隨著計算機(jī)能力不斷提升,開始支持多線程,那么就可能會問題了。我們分別來分析下單線程、多線程在單核CPU、多核CPU中的影響。

  • 單核cpu與單線程:核心的緩存只被一個線程訪問,緩存獨(dú)占,不會出現(xiàn)訪問沖突等問題。
  • 單核CPU與多線程:進(jìn)程中的多個線程會同時訪問進(jìn)程中的共享數(shù)據(jù),CPU將某塊內(nèi)存加載到緩存后,不同線程在訪問相同的物理地址的時候,都會映射到相同的緩存位置,這樣即使發(fā)生線程的切換,緩存仍然不會失效。但由于任何時刻只能有一個線程在執(zhí)行,因此不會出現(xiàn)緩存訪問沖突。
  • 多核CPU與多線程:每個核都至少有一個L1 緩存用于提升效率。當(dāng)多個線程分別在不同的核心上執(zhí)行且訪問進(jìn)程中的同個共享內(nèi)存,由于多核是可以并行的,則可能會出現(xiàn)類似多線程編程中出現(xiàn)的并發(fā)問題,如對于同一塊內(nèi)存中的變量,多個核心同時讀寫修改數(shù)據(jù)的話,就會出現(xiàn)不可預(yù)期的錯誤,而其解決思路則是通過鎖機(jī)制。

所以在CPU和主存之間增加緩存,在多核CPU多線程場景下發(fā)生并發(fā)內(nèi)存訪問操作時可能會出現(xiàn)歧義。

處理器優(yōu)化--“指令重排”

除了上面的問題之外,還有另一個硬件問題也比較重要:處理器為了使其內(nèi)部的運(yùn)算單元能夠被充分利用會進(jìn)行優(yōu)化,可能會亂序執(zhí)行處理輸入代碼,此處暫理解為“指令重排”。除了一些處理器會對代碼進(jìn)行優(yōu)化亂序處理外,很多編程語言的編譯器也會有類似的優(yōu)化,比如Java虛擬機(jī)的JIT即時編譯器也會做指令重排。

[[315410]]

如Java單例設(shè)計模式Double-Check例子中的voliate關(guān)鍵字應(yīng)用就是為了防止因指令重排導(dǎo)致在多線程并發(fā)場景下出現(xiàn)異常。感興趣的朋友可以參考我的另一篇文章深入解析單例模式--懶漢模式,這里就不再進(jìn)行過多的探討。

什么是內(nèi)存模型

上面分析了那么多其實(shí)目的是為了引出兩個重要問題:

  • 多核CPU多線程場景下發(fā)生并發(fā)內(nèi)存訪問操作時可能會出現(xiàn)歧義
  • 處理器為了使其內(nèi)部的運(yùn)算單元能夠被充分利用會自行進(jìn)行優(yōu)化--“指令重排”

那么對于以上問題該如何解決?這時候便引出了重要概念--內(nèi)存模型,定義如下:

內(nèi)存模型是對內(nèi)存進(jìn)行讀寫訪問過程的抽象,可以理解為內(nèi)存模型定義了共享內(nèi)存系統(tǒng)中讀寫操作行為的規(guī)范,通過這些規(guī)則來規(guī)范對內(nèi)存的讀寫操作,從而保證指令執(zhí)行的正確性。它與處理器有關(guān)、與緩存有關(guān)、與并發(fā)有關(guān)、與編譯器也有關(guān)。目的是為解決CPU多級緩存、處理器優(yōu)化、指令重排等導(dǎo)致的問題與歧義。

可以簡單理解為內(nèi)存模型其實(shí)就是解決多線程場景下因并發(fā)所導(dǎo)致的問題的一個重要規(guī)范。

[[315411]]

Java內(nèi)存模型

1. 定義

Java內(nèi)存模型(Java Memory Model ,JMM)就是一種符合內(nèi)存模型規(guī)范的,屏蔽了各種硬件和操作系統(tǒng)的訪問差異的,以實(shí)現(xiàn)讓Java程序在各種平臺下都能達(dá)到一致的內(nèi)存訪問效果的規(guī)范。

2. 理解

Java內(nèi)存模型(簡稱“JMM”)是一個規(guī)范,其主要目的是定義程序中各種變量的訪問規(guī)則,是圍繞著在并發(fā)過程中如何處理原子性、可見性和有序性三個特征來建立的。

循序漸進(jìn)--理解什么是Java內(nèi)存模型

關(guān)于Java內(nèi)存模型的實(shí)現(xiàn),相信熟悉Java并發(fā)編程的朋友一定會熟悉,Java提供了一系列和并發(fā)處理相關(guān)的關(guān)鍵字,其實(shí)這些就是Java內(nèi)存模型封裝了底層的實(shí)現(xiàn)后提供給程序員使用的一些關(guān)鍵字,本文在這里就不對這些關(guān)鍵字一一展開討論了,感興趣的朋友可以看看《Java多線程編程核心技術(shù)》進(jìn)行了解。其中如:

  • 通過使用volatile關(guān)鍵字解決因指令重排導(dǎo)致的問題
  • 通過synchronized關(guān)鍵字來保證線程安全等

等方式其實(shí)就與硬件通過計算機(jī)內(nèi)存模型中限制處理器優(yōu)化和使用內(nèi)存屏障等解決問題的思路一致。

循序漸進(jìn)--理解什么是Java內(nèi)存模型

最后

本文從硬件可能出現(xiàn)的問題引出計算機(jī)內(nèi)存模型解決方案,進(jìn)而提取出多線程并發(fā)問題。最后再引出Java內(nèi)存模型。Java內(nèi)存模型可以簡單理解就是一套圍繞著在并發(fā)過程中如何處理原子性、可見性和有序性三個特征來建立的規(guī)范,而如synchronized等關(guān)鍵字則是其具體實(shí)現(xiàn)。

 

責(zé)任編輯:趙寧寧 來源: 今日頭條
相關(guān)推薦

2019-06-25 09:02:44

加密加密算法密鑰

2010-12-28 16:49:05

2011-05-20 10:39:43

oracle

2009-08-26 14:25:46

C#消息

2012-03-01 22:37:02

Linux入門

2023-03-23 08:49:39

負(fù)載均衡服務(wù)器

2009-08-07 03:47:00

2011-05-24 13:47:25

程序員

2009-10-30 14:43:24

寬帶接入網(wǎng)

2010-12-28 16:38:16

Windows SerWindows 部署服

2022-04-21 14:03:54

開發(fā)API生命周期

2010-12-31 15:28:41

Windows 7

2024-07-04 08:00:00

2018-02-05 15:30:01

MariaDB服務(wù)器主從復(fù)制

2022-03-31 06:23:43

自動化響應(yīng)網(wǎng)絡(luò)安全

2010-01-06 16:40:30

cisco交換機(jī)vla

2022-04-29 11:27:26

循序漸進(jìn)!開展零信任

2020-11-23 11:09:18

大數(shù)據(jù)教育云計算

2020-07-17 10:37:08

云計算安全IT

2013-12-03 09:57:15

下一代互聯(lián)網(wǎng)IPv6遷移
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號