激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - 再有人問(wèn)你Java內(nèi)存模型是什么,就把這篇文章發(fā)給他

再有人問(wèn)你Java內(nèi)存模型是什么,就把這篇文章發(fā)給他

2020-12-11 23:34今日頭條Java非著名程序員 Java教程

本文中,有很多定義和說(shuō)法,都是筆者自己理解后定義出來(lái)的。希望能夠讓讀者可以對(duì)Java內(nèi)存模型有更加清晰的認(rèn)識(shí)。

再有人問(wèn)你Java內(nèi)存模型是什么,就把這篇文章發(fā)給他

本文中,有很多定義和說(shuō)法,都是筆者自己理解后定義出來(lái)的。希望能夠讓讀者可以對(duì)Java內(nèi)存模型有更加清晰的認(rèn)識(shí)。當(dāng)然,如有偏頗,歡迎指正。

為什么要有內(nèi)存模型

在介紹Java內(nèi)存模型之前,先來(lái)看一下到底什么是計(jì)算機(jī)內(nèi)存模型,然后再來(lái)看Java內(nèi)存模型在計(jì)算機(jī)內(nèi)存模型的基礎(chǔ)上做了哪些事情。要說(shuō)計(jì)算機(jī)的內(nèi)存模型,就要說(shuō)一下一段古老的歷史,看一下為什么要有內(nèi)存模型。

內(nèi)存模型,英文名Memory Model,他是一個(gè)很老的老古董了。他是與計(jì)算機(jī)硬件有關(guān)的一個(gè)概念。那么我先給你介紹下他和硬件到底有啥關(guān)系。

CPU和緩存一致性

我們應(yīng)該都知道,計(jì)算機(jī)在執(zhí)行程序的時(shí)候,每條指令都是在CPU中執(zhí)行的,而執(zhí)行的時(shí)候,又免不了要和數(shù)據(jù)打交道。而計(jì)算機(jī)上面的數(shù)據(jù),是存放在主存當(dāng)中的,也就是計(jì)算機(jī)的物理內(nèi)存啦。

剛開(kāi)始,還相安無(wú)事的,但是隨著CPU技術(shù)的發(fā)展,CPU的執(zhí)行速度越來(lái)越快。而由于內(nèi)存的技術(shù)并沒(méi)有太大的變化,所以從內(nèi)存中讀取和寫(xiě)入數(shù)據(jù)的過(guò)程和CPU的執(zhí)行速度比起來(lái)差距就會(huì)越來(lái)越大,這就導(dǎo)致CPU每次操作內(nèi)存都要耗費(fèi)很多等待時(shí)間。

  • 這就像一家創(chuàng)業(yè)公司,剛開(kāi)始,創(chuàng)始人和員工之間工作關(guān)系其樂(lè)融融,但是隨著創(chuàng)始人的能力和野心越來(lái)越大,逐漸和員工之間出現(xiàn)了差距,普通員工原來(lái)越跟不上CEO的腳步。老板的每一個(gè)命令,傳到到基層員工之后,由于基層員工的理解能力、執(zhí)行能力的欠缺,就會(huì)耗費(fèi)很多時(shí)間。這也就無(wú)形中拖慢了整家公司的工作效率。

可是,不能因?yàn)閮?nèi)存的讀寫(xiě)速度慢,就不發(fā)展CPU技術(shù)了吧,總不能讓內(nèi)存成為計(jì)算機(jī)處理的瓶頸吧。

所以,人們想出來(lái)了一個(gè)好的辦法,就是在CPU和內(nèi)存之間增加高速緩存。緩存的概念大家都知道,就是保存一份數(shù)據(jù)拷貝。他的特點(diǎn)是速度快,內(nèi)存小,并且昂貴。

那么,程序的執(zhí)行過(guò)程就變成了:

當(dāng)程序在運(yùn)行過(guò)程中,會(huì)將運(yùn)算需要的數(shù)據(jù)從主存復(fù)制一份到CPU的高速緩存當(dāng)中,那么CPU進(jìn)行計(jì)算時(shí)就可以直接從它的高速緩存讀取數(shù)據(jù)和向其中寫(xiě)入數(shù)據(jù),當(dāng)運(yùn)算結(jié)束之后,再將高速緩存中的數(shù)據(jù)刷新到主存當(dāng)中。

  • 之后,這家公司開(kāi)始設(shè)立中層管理人員,管理人員直接歸CEO領(lǐng)導(dǎo),領(lǐng)導(dǎo)有什么指示,直接告訴管理人員,然后就可以去做自己的事情了。管理人員負(fù)責(zé)去協(xié)調(diào)底層員工的工作。因?yàn)楣芾砣藛T是了解手下的人員以及自己負(fù)責(zé)的事情的。所以,大多數(shù)時(shí)候,公司的各種決策,通知等,CEO只要和管理人員之間溝通就夠了。

而隨著CPU能力的不斷提升,一層緩存就慢慢的無(wú)法滿足要求了,就逐漸的衍生出多級(jí)緩存。

按照數(shù)據(jù)讀取順序和與CPU結(jié)合的緊密程度,CPU緩存可以分為一級(jí)緩存(L1),二級(jí)緩存(L3),部分高端CPU還具有三級(jí)緩存(L3),每一級(jí)緩存中所儲(chǔ)存的全部數(shù)據(jù)都是下一級(jí)緩存的一部分。

這三種緩存的技術(shù)難度和制造成本是相對(duì)遞減的,所以其容量也是相對(duì)遞增的。

那么,在有了多級(jí)緩存之后,程序的執(zhí)行就變成了:

當(dāng)CPU要讀取一個(gè)數(shù)據(jù)時(shí),首先從一級(jí)緩存中查找,如果沒(méi)有找到再?gòu)亩?jí)緩存中查找,如果還是沒(méi)有就從三級(jí)緩存或內(nèi)存中查找。

  • 隨著公司越來(lái)越大,老板要管的事情越來(lái)越多,公司的管理部門開(kāi)始改革,開(kāi)始出現(xiàn)高層,中層,底層等管理者。一級(jí)一級(jí)之間逐層管理。

單核CPU只含有一套L1,L2,L3緩存;

如果CPU含有多個(gè)核心,即多核CPU,則每個(gè)核心都含有一套L1(甚至和L2)緩存,而共享L3(或者和L2)緩存。

  • 公司也分很多種,有些公司只有一個(gè)大Boss,他一個(gè)人說(shuō)了算。但是有些公司有比如聯(lián)席總經(jīng)理、合伙人等機(jī)制。
  • 單核CPU就像一家公司只有一個(gè)老板,所有命令都來(lái)自于他,那么就只需要一套管理班底就夠了。
  • 多核CPU就像一家公司是由多個(gè)合伙人共同創(chuàng)辦的,那么,就需要給每個(gè)合伙人都設(shè)立一套供自己直接領(lǐng)導(dǎo)的高層管理人員,多個(gè)合伙人共享使用的是公司的底層員工。
  • 還有的公司,不斷壯大,開(kāi)始差分出各個(gè)子公司。各個(gè)子公司就是多個(gè)CPU了,互相之前沒(méi)有共用的資源。互不影響。

下圖為一個(gè)單CPU雙核的緩存結(jié)構(gòu)。

再有人問(wèn)你Java內(nèi)存模型是什么,就把這篇文章發(fā)給他

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

單線程。cpu核心的緩存只被一個(gè)線程訪問(wèn)。緩存獨(dú)占,不會(huì)出現(xiàn)訪問(wèn)沖突等問(wèn)題。

單核CPU,多線程。進(jìn)程中的多個(gè)線程會(huì)同時(shí)訪問(wèn)進(jìn)程中的共享數(shù)據(jù),CPU將某塊內(nèi)存加載到緩存后,不同線程在訪問(wèn)相同的物理地址的時(shí)候,都會(huì)映射到相同的緩存位置,這樣即使發(fā)生線程的切換,緩存仍然不會(huì)失效。但由于任何時(shí)刻只能有一個(gè)線程在執(zhí)行,因此不會(huì)出現(xiàn)緩存訪問(wèn)沖突。

多核CPU,多線程。每個(gè)核都至少有一個(gè)L1 緩存。多個(gè)線程訪問(wèn)進(jìn)程中的某個(gè)共享內(nèi)存,且這多個(gè)線程分別在不同的核心上執(zhí)行,則每個(gè)核心都會(huì)在各自的caehe中保留一份共享內(nèi)存的緩沖。由于多核是可以并行的,可能會(huì)出現(xiàn)多個(gè)線程同時(shí)寫(xiě)各自的緩存的情況,而各自的cache之間的數(shù)據(jù)就有可能不同。

在CPU和主存之間增加緩存,在多線程場(chǎng)景下就可能存在緩存一致性問(wèn)題,也就是說(shuō),在多核CPU中,每個(gè)核的自己的緩存中,關(guān)于同一個(gè)數(shù)據(jù)的緩存內(nèi)容可能不一致。

  • 如果這家公司的命令都是串行下發(fā)的話,那么就沒(méi)有任何問(wèn)題。
  • 如果這家公司的命令都是并行下發(fā)的話,并且這些命令都是由同一個(gè)CEO下發(fā)的,這種機(jī)制是也沒(méi)有什么問(wèn)題。因?yàn)樗拿顖?zhí)行者只有一套管理體系。
  • 如果這家公司的命令都是并行下發(fā)的話,并且這些命令是由多個(gè)合伙人下發(fā)的,這就有問(wèn)題了。因?yàn)槊總€(gè)合伙人只會(huì)把命令下達(dá)給自己直屬的管理人員,而多個(gè)管理人員管理的底層員工可能是公用的。
  • 比如,合伙人1要辭退員工a,合伙人2要給員工a升職,升職后的話他再被辭退需要多個(gè)合伙人開(kāi)會(huì)決議。兩個(gè)合伙人分別把命令下發(fā)給了自己的管理人員。合伙人1命令下達(dá)后,管理人員a在辭退了員工后,他就知道這個(gè)員工被開(kāi)除了。而合伙人2的管理人員2這時(shí)候在沒(méi)得到消息之前,還認(rèn)為員工a是在職的,他就欣然的接收了合伙人給他的升職a的命令。
再有人問(wèn)你Java內(nèi)存模型是什么,就把這篇文章發(fā)給他

處理器優(yōu)化和指令重排

上面提到在在CPU和主存之間增加緩存,在多線程場(chǎng)景下會(huì)存在緩存一致性問(wèn)題。除了這種情況,還有一種硬件問(wèn)題也比較重要。那就是為了使處理器內(nèi)部的運(yùn)算單元能夠盡量的被充分利用,處理器可能會(huì)對(duì)輸入代碼進(jìn)行亂序執(zhí)行處理。這就是處理器優(yōu)化。

除了現(xiàn)在很多流行的處理器會(huì)對(duì)代碼進(jìn)行優(yōu)化亂序處理,很多編程語(yǔ)言的編譯器也會(huì)有類似的優(yōu)化,比如Java虛擬機(jī)的即時(shí)編譯器(JIT)也會(huì)做指令重排。

可想而知,如果任由處理器優(yōu)化和編譯器對(duì)指令重排的話,就可能導(dǎo)致各種各樣的問(wèn)題。

  • 關(guān)于員工組織調(diào)整的情況,如果允許人事部在接到多個(gè)命令后進(jìn)行隨意拆分亂序執(zhí)行或者重排的話,那么對(duì)于這個(gè)員工以及這家公司的影響是非常大的。

并發(fā)編程的問(wèn)題

前面說(shuō)的和硬件有關(guān)的概念你可能聽(tīng)得有點(diǎn)蒙,還不知道他到底和軟件有啥關(guān)系。但是關(guān)于并發(fā)編程的問(wèn)題你應(yīng)該有所了解,比如原子性問(wèn)題,可見(jiàn)性問(wèn)題和有序性問(wèn)題。

其實(shí),原子性問(wèn)題,可見(jiàn)性問(wèn)題和有序性問(wèn)題。是人們抽象定義出來(lái)的。而這個(gè)抽象的底層問(wèn)題就是前面提到的緩存一致性問(wèn)題、處理器優(yōu)化問(wèn)題和指令重排問(wèn)題等。

這里簡(jiǎn)單回顧下這三個(gè)問(wèn)題,并不準(zhǔn)備深入展開(kāi),感興趣的讀者可以自行學(xué)習(xí)。我們說(shuō),并發(fā)編程,為了保證數(shù)據(jù)的安全,需要滿足以下三個(gè)特性:

原子性是指在一個(gè)操作中就是cpu不可以在中途暫停然后再調(diào)度,既不被中斷操作,要不執(zhí)行完成,要不就不執(zhí)行。

可見(jiàn)性是指當(dāng)多個(gè)線程訪問(wèn)同一個(gè)變量時(shí),一個(gè)線程修改了這個(gè)變量的值,其他線程能夠立即看得到修改的值。

有序性即程序執(zhí)行的順序按照代碼的先后順序執(zhí)行。

有沒(méi)有發(fā)現(xiàn),緩存一致性問(wèn)題其實(shí)就是可見(jiàn)性問(wèn)題。而處理器優(yōu)化是可以導(dǎo)致原子性問(wèn)題的。指令重排即會(huì)導(dǎo)致有序性問(wèn)題。所以,后文將不再提起硬件層面的那些概念,而是直接使用大家熟悉的原子性、可見(jiàn)性和有序性。

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

前面提到的,緩存一致性問(wèn)題、處理器器優(yōu)化的指令重排問(wèn)題是硬件的不斷升級(jí)導(dǎo)致的。那么,有沒(méi)有什么機(jī)制可以很好的解決上面的這些問(wèn)題呢?

最簡(jiǎn)單直接的做法就是廢除處理器和處理器的優(yōu)化技術(shù)、廢除CPU緩存,讓CPU直接和主存交互。但是,這么做雖然可以保證多線程下的并發(fā)問(wèn)題。但是,這就有點(diǎn)因噎廢食了。

所以,為了保證并發(fā)編程中可以滿足原子性、可見(jiàn)性及有序性。有一個(gè)重要的概念,那就是——內(nèi)存模型。

為了保證共享內(nèi)存的正確性(可見(jiàn)性、有序性、原子性),內(nèi)存模型定義了共享內(nèi)存系統(tǒng)中多線程程序讀寫(xiě)操作行為的規(guī)范。通過(guò)這些規(guī)則來(lái)規(guī)范對(duì)內(nèi)存的讀寫(xiě)操作,從而保證指令執(zhí)行的正確性。它與處理器有關(guān)、與緩存有關(guān)、與并發(fā)有關(guān)、與編譯器也有關(guān)。他解決了CPU多級(jí)緩存、處理器優(yōu)化、指令重排等導(dǎo)致的內(nèi)存訪問(wèn)問(wèn)題,保證了并發(fā)場(chǎng)景下的一致性、原子性和有序性。

內(nèi)存模型解決并發(fā)問(wèn)題主要采用兩種方式:限制處理器優(yōu)化使用內(nèi)存屏障。本文就不深入底層原理來(lái)展開(kāi)介紹了,感興趣的朋友可以自行學(xué)習(xí)。

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

前面介紹過(guò)了計(jì)算機(jī)內(nèi)存模型,這是解決多線程場(chǎng)景下并發(fā)問(wèn)題的一個(gè)重要規(guī)范。那么具體的實(shí)現(xiàn)是如何的呢,不同的編程語(yǔ)言,在實(shí)現(xiàn)上可能有所不同。

我們知道,Java程序是需要運(yùn)行在Java虛擬機(jī)上面的,Java內(nèi)存模型(Java Memory Model ,JMM)就是一種符合內(nèi)存模型規(guī)范的,屏蔽了各種硬件和操作系統(tǒng)的訪問(wèn)差異的,保證了Java程序在各種平臺(tái)下對(duì)內(nèi)存的訪問(wèn)都能保證效果一致的機(jī)制及規(guī)范。

提到Java內(nèi)存模型,一般指的是JDK 5 開(kāi)始使用的新的內(nèi)存模型,主要由JSR-133: JavaTM Memory Model and Thread Specification 描述。感興趣的可以參看下這份PDF文檔(http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf)

Java內(nèi)存模型規(guī)定了所有的變量都存儲(chǔ)在主內(nèi)存中,每條線程還有自己的工作內(nèi)存,線程的工作內(nèi)存中保存了該線程中是用到的變量的主內(nèi)存副本拷貝,線程對(duì)變量的所有操作都必須在工作內(nèi)存中進(jìn)行,而不能直接讀寫(xiě)主內(nèi)存。不同的線程之間也無(wú)法直接訪問(wèn)對(duì)方工作內(nèi)存中的變量,線程間變量的傳遞均需要自己的工作內(nèi)存和主存之間進(jìn)行數(shù)據(jù)同步進(jìn)行。

而JMM就作用于工作內(nèi)存和主存之間數(shù)據(jù)同步過(guò)程。他規(guī)定了如何做數(shù)據(jù)同步以及什么時(shí)候做數(shù)據(jù)同步。

再有人問(wèn)你Java內(nèi)存模型是什么,就把這篇文章發(fā)給他

這里面提到的主內(nèi)存和工作內(nèi)存,讀者可以簡(jiǎn)單的類比成計(jì)算機(jī)內(nèi)存模型中的主存和緩存的概念。特別需要注意的是,主內(nèi)存和工作內(nèi)存與JVM內(nèi)存結(jié)構(gòu)中的Java堆、棧、方法區(qū)等并不是同一個(gè)層次的內(nèi)存劃分,無(wú)法直接類比。《深入理解Java虛擬機(jī)》中認(rèn)為,如果一定要勉強(qiáng)對(duì)應(yīng)起來(lái)的話,從變量、主內(nèi)存、工作內(nèi)存的定義來(lái)看,主內(nèi)存主要對(duì)應(yīng)于Java堆中的對(duì)象實(shí)例數(shù)據(jù)部分。工作內(nèi)存則對(duì)應(yīng)于虛擬機(jī)棧中的部分區(qū)域。

所以,再來(lái)總結(jié)下,JMM是一種規(guī)范,目的是解決由于多線程通過(guò)共享內(nèi)存進(jìn)行通信時(shí),存在的本地內(nèi)存數(shù)據(jù)不一致、編譯器會(huì)對(duì)代碼指令重排序、處理器會(huì)對(duì)代碼亂序執(zhí)行等帶來(lái)的問(wèn)題。目的是保證并發(fā)編程場(chǎng)景中的原子性、可見(jiàn)性和有序性。

 Java內(nèi)存模型的實(shí)現(xiàn)

了解Java多線程的朋友都知道,在Java中提供了一系列和并發(fā)處理相關(guān)的關(guān)鍵字,比如volatile、synchronized、final、concurren包等。其實(shí)這些就是Java內(nèi)存模型封裝了底層的實(shí)現(xiàn)后提供給程序員使用的一些關(guān)鍵字。

在開(kāi)發(fā)多線程的代碼的時(shí)候,我們可以直接使用synchronized等關(guān)鍵字來(lái)控制并發(fā),從來(lái)就不需要關(guān)心底層的編譯器優(yōu)化、緩存一致性等問(wèn)題。所以,Java內(nèi)存模型,除了定義了一套規(guī)范,還提供了一系列原語(yǔ),封裝了底層實(shí)現(xiàn)后,供開(kāi)發(fā)者直接使用。

本文并不準(zhǔn)備把所有的關(guān)鍵字逐一介紹其用法,因?yàn)殛P(guān)于各個(gè)關(guān)鍵字的用法,網(wǎng)上有很多資料。讀者可以自行學(xué)習(xí)。本文還有一個(gè)重點(diǎn)要介紹的就是,我們前面提到,并發(fā)編程要解決原子性、有序性和一致性的問(wèn)題,我們就再來(lái)看下,在Java中,分別使用什么方式來(lái)保證。

原子性

在Java中,為了保證原子性,提供了兩個(gè)高級(jí)的字節(jié)碼指令monitorentermonitorexit。在synchronized的實(shí)現(xiàn)原理文章中,介紹過(guò),這兩個(gè)字節(jié)碼,在Java中對(duì)應(yīng)的關(guān)鍵字就是synchronized。

因此,在Java中可以使用synchronized來(lái)保證方法和代碼塊內(nèi)的操作是原子性的。

可見(jiàn)性

Java內(nèi)存模型是通過(guò)在變量修改后將新值同步回主內(nèi)存,在變量讀取前從主內(nèi)存刷新變量值的這種依賴主內(nèi)存作為傳遞媒介的方式來(lái)實(shí)現(xiàn)的。

Java中的volatile關(guān)鍵字提供了一個(gè)功能,那就是被其修飾的變量在被修改后可以立即同步到主內(nèi)存,被其修飾的變量在每次是用之前都從主內(nèi)存刷新。因此,可以使用volatile來(lái)保證多線程操作時(shí)變量的可見(jiàn)性。

除了volatile,Java中的synchronizedfinal兩個(gè)關(guān)鍵字也可以實(shí)現(xiàn)可見(jiàn)性。只不過(guò)實(shí)現(xiàn)方式不同,這里不再展開(kāi)了。

有序性

在Java中,可以使用synchronizedvolatile來(lái)保證多線程之間操作的有序性。實(shí)現(xiàn)方式有所區(qū)別:

volatile關(guān)鍵字會(huì)禁止指令重排。synchronized關(guān)鍵字保證同一時(shí)刻只允許一條線程操作。

好了,這里簡(jiǎn)單的介紹完了Java并發(fā)編程中解決原子性、可見(jiàn)性以及有序性可以使用的關(guān)鍵字。讀者可能發(fā)現(xiàn)了,好像synchronized關(guān)鍵字是萬(wàn)能的,他可以同時(shí)滿足以上三種特性,這其實(shí)也是很多人濫用synchronized的原因。

但是synchronized是比較影響性能的,雖然編譯器提供了很多鎖優(yōu)化技術(shù),但是也不建議過(guò)度使用。

總結(jié)再有人問(wèn)你Java內(nèi)存模型是什么,就把這篇文章發(fā)給他

在讀完本文之后,相信你應(yīng)該了解了什么是Java內(nèi)存模型、Java內(nèi)存模型的作用以及Java中內(nèi)存模型做了什么事情等。

原文地址:https://www.toutiao.com/i6901560023457989131/

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 国产成人综合在线视频 | 欧美 videos粗暴| 91看片网页 | 久色婷婷 | 免费a视频在线观看 | 国产91中文字幕 | 久久99精品久久久久久小说 | 中国一级免费视频 | 91午夜在线观看 | 一级做受毛片免费大片 | 欧美性a视频 | 视频一区二区在线观看 | av在线在线| 欧美在线国产 | 国产免费久久久久 | 成人不卡在线观看 | 欧美成a人片在线观看久 | 久久毛片| 欧美成人免费一区二区三区 | 在线成人免费网站 | 在线观看免费精品 | 日本不卡一区在线观看 | av免费在线观看国产 | 国产免费成人 | 天天操综 | 亚洲精品日韩色噜噜久久五月 | 美女羞羞视频网站 | 涩涩屋av | 成人爱爱电影 | 羞羞网站 | 日韩欧美色综合 | 精品一区二区三区中文字幕老牛 | 中文字幕在线观看日韩 | 免费黄色在线电影 | 国产成人av一区二区 | xx53xx| 国产在线一级片 | 国产精品久久久久久久不卡 | 成人性爱视频在线观看 | 国产亚洲精品久久久久久久久久 | 精品欧美一区二区精品久久 |