偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

也許是東半球最叼的Java內(nèi)存模型

開(kāi)發(fā) 后端
單核CPU 的多線程也會(huì)出現(xiàn)上面的線程不安全的問(wèn)題,只是產(chǎn)生原因不是多核CPU緩存不一致的問(wèn)題導(dǎo)致,而是CPU調(diào)度線程切換,多線程局部變量不同步引起的。

[[406082]]

面試官:你好,你先自我介紹一下。

安琪拉:面試官你好,我叫安琪拉,草叢三婊,最強(qiáng)中單,草地摩托車(chē)車(chē)手,第21套廣播體操推廣者,火球擁有者、不焚者,安琪拉,這是我的簡(jiǎn)歷,請(qǐng)過(guò)目。

面試官:看你簡(jiǎn)歷上寫(xiě)熟悉多線程編程,跟我講講Java內(nèi)存模型。

安琪拉:講Java內(nèi)存模型前我希望給您講一個(gè)故事,從CPU的發(fā)展史說(shuō)起。

面試官:我喜歡聽(tīng)故事,你說(shuō)吧。

安琪拉: 先說(shuō)現(xiàn)代CPU 架構(gòu)的形成,一切要從馮洛伊曼計(jì)算機(jī)體系開(kāi)始說(shuō)起!

面試官: 扯的是不是有點(diǎn)遠(yuǎn),你能不能快點(diǎn)進(jìn)入主題!

安琪拉: 你對(duì)一個(gè)從上海開(kāi)3個(gè)小時(shí)車(chē)來(lái)杭州,真心誠(chéng)意求職的人就這么沒(méi)有耐心的。

面試官: 孽緣,真是孽緣。你講吧。

安琪拉: 下圖就是經(jīng)典的 馮洛伊曼體系結(jié)構(gòu),基本把計(jì)算機(jī)的組成模塊都定義好了,現(xiàn)在的計(jì)算機(jī)都是以這個(gè)體系弄的,其中最核心的就是由運(yùn)算器和控制器組成的中央處理器,就是我們常說(shuō)的CPU。

馮洛伊曼體系結(jié)構(gòu)

面試官: 這個(gè)跟Java內(nèi)存模型有什么關(guān)系?

安琪拉: 不要著急嘛!

安琪拉: 剛才說(shuō)到馮洛伊曼體系中的CPU,你應(yīng)該聽(tīng)過(guò)摩爾定律吧!就是英特爾創(chuàng)始人戈登·摩爾講的:

集成電路上可容納的晶體管數(shù)目,約每隔18個(gè)月便會(huì)增加一倍,性能也將提升一倍。

面試官: 聽(tīng)過(guò)的,然后呢?

安琪拉:所以你看到我們電腦CPU 的性能越來(lái)越強(qiáng)勁,英特爾CPU 從Intel Core 一直到 Intel Core i7,前些年單核CPU 的晶體管數(shù)量確實(shí)符合摩爾定律,看下面這張圖。

摩爾定律

橫軸為新CPU發(fā)明的年份,縱軸為可容納晶體管的對(duì)數(shù)。所有的點(diǎn)近似成一條直線,這意味著晶體管數(shù)目隨年份呈指數(shù)變化,大概每?jī)赡攴环?/p>

面試官: 后來(lái)呢?

安琪拉:別著急啊!后來(lái)摩爾定律越來(lái)越撐不住了,但是更新?lián)Q代的程序?qū)﹄娔X性能的期望和要求還在不斷上漲,就出現(xiàn)了下面的劇情。

[[406084]]

再不轉(zhuǎn)發(fā)我也要跪了

他為其Pentium 4新一代芯片取消上市而道歉, 近幾年來(lái),英特爾不斷地在增加其處理器的運(yùn)行速度。當(dāng)前最快的一款,其速度已達(dá)3.4GHz,雖然強(qiáng)化處理器的運(yùn)行速度,也增強(qiáng)了芯片運(yùn)作效能,但速度提升卻使得芯片的能源消耗量增加,并衍生出冷卻芯片的問(wèn)題。

因此,英特爾摒棄將心力集中在提升運(yùn)行速度的做法,在未來(lái)幾年,將其芯片轉(zhuǎn)為以多模核心(multi-core)的方式設(shè)計(jì)等其他方式,來(lái)提升芯片的表現(xiàn)。多模核心的設(shè)計(jì)法是將多模核心置入單一芯片中。如此一來(lái),這些核心芯片即能以較緩慢的速度運(yùn)轉(zhuǎn),除了可減少運(yùn)轉(zhuǎn)消耗的能量,也能減少運(yùn)轉(zhuǎn)生成的熱量。此外,集眾核心芯片之力,可提供較單一核心芯片更大的處理能力。—《經(jīng)濟(jì)學(xué)人》

安琪拉:當(dāng)然上面貝瑞特當(dāng)然只是在開(kāi)玩笑,眼看摩爾定律撐不住了,后來(lái)怎么處理的呢?一顆CPU 不行,我們多來(lái)幾顆嘛!這就是現(xiàn)在我們常見(jiàn)的多核CPU,四核8G 聽(tīng)著熟悉不熟悉?當(dāng)然完全依據(jù)馮洛伊曼體系設(shè)計(jì)的計(jì)算機(jī)也是有缺陷的!

面試官: 什么缺陷?說(shuō)說(shuō)看。

安琪拉:CPU 運(yùn)算器的運(yùn)算速度遠(yuǎn)比內(nèi)存讀寫(xiě)速度快,所以CPU 大部分時(shí)間都在等數(shù)據(jù)從內(nèi)存讀取,運(yùn)算完數(shù)據(jù)寫(xiě)回內(nèi)存。

面試官: 那怎么解決?

安琪拉:因?yàn)镃PU 運(yùn)行速度實(shí)在太快,主存(就是內(nèi)存)的數(shù)據(jù)讀取速度和CPU 運(yùn)算速度差了有幾個(gè)數(shù)量級(jí),因此現(xiàn)代計(jì)算機(jī)系統(tǒng)通過(guò)在CPU 和主存之前加了一層讀寫(xiě)速度盡可能接近CPU 運(yùn)行速度的高速緩存來(lái)做數(shù)據(jù)緩沖,這樣緩存提前從主存獲取數(shù)據(jù),CPU 不再?gòu)闹鞔嫒?shù)據(jù),而是從緩存取數(shù)據(jù)。這樣就緩解由于主存速度太慢導(dǎo)致的CPU 饑餓的問(wèn)題。同時(shí)CPU 內(nèi)還有寄存器,一些計(jì)算的中間結(jié)果臨時(shí)放在寄存器內(nèi)。

面試官: 既然你提到緩存,那我問(wèn)你一個(gè)問(wèn)題,CPU 從緩存讀取數(shù)據(jù)和從內(nèi)存讀取數(shù)據(jù)除了讀取速度的差異?有什么本質(zhì)的區(qū)別嗎?不都是讀數(shù)據(jù)寫(xiě)數(shù)據(jù),而且加緩存會(huì)讓整個(gè)體系結(jié)構(gòu)變得更加復(fù)雜。

安琪拉:緩存和主存不僅僅是讀取寫(xiě)入數(shù)據(jù)速度上的差異,還有另外更大的區(qū)別:研究人員發(fā)現(xiàn)了程序80%的時(shí)間在運(yùn)行20% 的代碼,所以緩存本質(zhì)上只要把20%的常用數(shù)據(jù)和指令放進(jìn)來(lái)就可以了(是不是和Redis 存放熱點(diǎn)數(shù)據(jù)很像),另外CPU 訪問(wèn)主存數(shù)據(jù)時(shí)存在二個(gè)局部性現(xiàn)象:

  • 時(shí)間局部性現(xiàn)象

如果一個(gè)主存數(shù)據(jù)正在被訪問(wèn),那么在近期它被再次訪問(wèn)的概率非常大。想想你程序大部分時(shí)間是不是在運(yùn)行主流程20%的代碼。

  • 空間局部性現(xiàn)象

CPU使用到某塊內(nèi)存區(qū)域數(shù)據(jù),這塊內(nèi)存區(qū)域后面臨近的數(shù)據(jù)很大概率立即會(huì)被使用到。這個(gè)很好解釋?zhuān)覀兂绦蚪?jīng)常用的數(shù)組、集合(本質(zhì)也是數(shù)組)經(jīng)常會(huì)順序訪問(wèn)(內(nèi)存地址連續(xù)或鄰近)。

因?yàn)檫@二個(gè)局部性現(xiàn)象的存在使得緩存的存在可以很大程度上緩解CPU 饑餓的問(wèn)題。

面試官: 講的是那么回事,那能給我畫(huà)一下現(xiàn)在CPU、緩存、主存的關(guān)系圖嗎?

安琪拉:可以。我們來(lái)看下現(xiàn)在主流的多核CPU的硬件架構(gòu),如下圖所示。

多核心CPU架構(gòu)

多核心CPU架構(gòu)

安琪拉:現(xiàn)代操作系統(tǒng)一般會(huì)有多級(jí)緩存(Cache Line),一般有L1、L2,甚至有L3,看下安琪拉的電腦緩存信息,一共4核,三級(jí)緩存,L1 緩存(在CPU核心內(nèi))這里沒(méi)有顯示出來(lái),這里L(fēng)2 緩存后面括號(hào)標(biāo)識(shí)了是每個(gè)核都有L2 緩存,而L3 緩存沒(méi)有標(biāo)識(shí),是因?yàn)長(zhǎng)3 緩存是4個(gè)核共享的緩存:

安琪拉的電腦緩存

安琪拉的電腦多級(jí)緩存

面試官: 那你能跟我簡(jiǎn)單講講程序運(yùn)行時(shí),數(shù)據(jù)是怎么在主存、緩存、CPU寄存器之間流轉(zhuǎn)的嗎?

安琪拉:可以。比如以 i = i + 2; 為例, 當(dāng)線程執(zhí)行到這條語(yǔ)句時(shí),會(huì)先從主存中讀取i 的值,然后復(fù)制一份到緩存中,CPU 讀取緩存數(shù)據(jù)(取數(shù)指令),進(jìn)行 i + 2 操作(中間數(shù)據(jù)放寄存器),然后把結(jié)果寫(xiě)入緩存,最后將緩存中i最新的值刷新到主存當(dāng)中(寫(xiě)回主存時(shí)間不確定)。

面試官: 這個(gè)數(shù)據(jù)操作邏輯在單線程環(huán)境和多線程環(huán)境下有什么區(qū)別?

安琪拉:比如i 如果是共享變量(例如類(lèi)的成員變量),單線程運(yùn)行沒(méi)有任何問(wèn)題,但是多線程中運(yùn)行就有可能出問(wèn)題。

例如:有A、B二個(gè)線程,在二個(gè)不同的CPU 上運(yùn)行,因?yàn)槊總€(gè)線程運(yùn)行的CPU 都有自己的緩存,i是共享變量,初始值是0,A 線程從內(nèi)存讀取i 的值存入緩存,B 線程此時(shí)也讀取i 的值存入自己CPU的緩存,A 線程對(duì)i 進(jìn)行+1操作,i變成了1,B線程緩存中的變量 i 還是0,B線程也對(duì)i 進(jìn)行+1操作,最后A、B線程先后將緩存數(shù)據(jù)寫(xiě)回內(nèi)存共享區(qū),預(yù)期的結(jié)果應(yīng)該是2,因?yàn)榘l(fā)生了二次+1操作,但是實(shí)際是1。

執(zhí)行過(guò)程如下圖:

緩存不一致

緩存不一致

這個(gè)就是非常著名的緩存一致性問(wèn)題,注意這里還只是多CPU的緩存一致性問(wèn)題,和我們常說(shuō)的多線程共享變量安全問(wèn)題還不相同。

說(shuō)明:?jiǎn)魏薈PU 的多線程也會(huì)出現(xiàn)上面的線程不安全的問(wèn)題,只是產(chǎn)生原因不是多核CPU緩存不一致的問(wèn)題導(dǎo)致,而是CPU調(diào)度線程切換,多線程局部變量不同步引起的。

面試官: 那CPU 怎么解決緩存一致性問(wèn)題呢?

安琪拉:早期的一些CPU 設(shè)計(jì)中,是通過(guò)鎖總線(總線訪問(wèn)加Lock# 鎖)的方式解決的。看下CPU 體系結(jié)構(gòu)圖,如下:

CPU內(nèi)體系結(jié)構(gòu)

CPU內(nèi)體系結(jié)構(gòu)

因?yàn)镃PU 都是通過(guò)總線來(lái)讀取主存中的數(shù)據(jù),因此對(duì)總線加Lock# 鎖的話,其他CPU 訪問(wèn)主存就被阻塞了,這樣防止了對(duì)共享變量的競(jìng)爭(zhēng)。但是鎖總線對(duì)CPU的性能損耗非常大,把多核CPU 并行的優(yōu)勢(shì)直接給干沒(méi)了!(還記得并發(fā)第一集的并行知識(shí)吧)

后面研究人員就搞出了一套協(xié)議:緩存一致性協(xié)議。協(xié)議的類(lèi)型很多(MSI、MESI、MOSI、Synapse、Firefly),最常見(jiàn)的就是Intel (英特爾)的MESI 協(xié)議。緩存一致性協(xié)議主要規(guī)范了CPU 讀寫(xiě)主存、管理緩存數(shù)據(jù)的一系列規(guī)范,如下圖所示。

緩存一致性協(xié)議

面試官: 那講講緩存一致性協(xié)議(MESI協(xié)議)唄!

安琪拉: 緩存一致性協(xié)議(MESI協(xié)議)的核心思想:

  • 定義了緩存中的數(shù)據(jù)狀態(tài)只有四種,MESI 是四種狀態(tài)的首字母。
  • 當(dāng)CPU寫(xiě)數(shù)據(jù)時(shí),如果寫(xiě)的變量是共享變量,即在其他CPU中也存在該變量的副本,會(huì)發(fā)出信號(hào)通知其他CPU將該變量的緩存行置為無(wú)效狀態(tài);
  • 當(dāng)CPU讀取共享變量時(shí),發(fā)現(xiàn)自己緩存的該變量的緩存行是無(wú)效的,那么它就會(huì)從內(nèi)存中重新讀取。

緩存中數(shù)據(jù)都是以緩存行(Cache Line)為單位存儲(chǔ);MESI 各個(gè)狀態(tài)描述如下表所示:

面試官: MESI 協(xié)議解決了什么問(wèn)題?

安琪拉: 解決了**多核CPU **緩存不一致的問(wèn)題。

面試官: 那我有個(gè)疑問(wèn)了,既然有MESI 的存在,解決多核CPU的緩存一致性,為什么還需要Java用volatile 這種關(guān)鍵字?

因?yàn)槲覀冎纕olatile 也是保證共享變量的可見(jiàn)性。

安琪拉: volatile是Java語(yǔ)言層面來(lái)定義的,Java語(yǔ)言實(shí)現(xiàn)volatile 的內(nèi)存可見(jiàn)性需要借助MESI,但是有的CPU只有單核、或者不支持MESI、那怎么實(shí)現(xiàn)內(nèi)存可見(jiàn)呢?可以是通過(guò)鎖總線的方式,volatile屏蔽了硬件的差異,說(shuō)直接點(diǎn):使用volatile 修飾的變量是有內(nèi)存可見(jiàn)性的,這是Java 語(yǔ)法定的,Java 不關(guān)心你底層操作系統(tǒng)、硬件CPU 是如何實(shí)現(xiàn)內(nèi)存可見(jiàn)的,我的語(yǔ)法規(guī)定就是volatile 修飾的變量必須是具有可見(jiàn)性的。

虛擬機(jī)實(shí)現(xiàn)volatile的方式是寫(xiě)入了一條lock 前綴的匯編指令,lock 前綴的匯編指令會(huì)強(qiáng)制變量寫(xiě)入主存,也可避免前后指令的CPU重排序,并及時(shí)讓其他核中的相應(yīng)緩存行失效,volatile是利用MESI達(dá)到符合預(yù)期的效果。

面試官: 你故事講完了嗎?可以說(shuō)說(shuō)為什么需要Java內(nèi)存模型了吧?

安琪拉: CPU 有X86(復(fù)雜指令集)、ARM(精簡(jiǎn)指令集)等體系架構(gòu),版本類(lèi)型也有很多種,CPU 可能通過(guò)鎖總線、MESI 協(xié)議實(shí)現(xiàn)多核心緩存的一致性。因?yàn)橛杏布牟町愐约熬幾g器和處理器的指令重排優(yōu)化的存在,所以Java 需要一種協(xié)議來(lái)規(guī)避硬件平臺(tái)的差異,保障同一段代碼在所有平臺(tái)運(yùn)行效果一致,這個(gè)協(xié)議叫做Java 內(nèi)存模型(Java Memory Model)。

面試官: 詳細(xì)說(shuō)說(shuō)。

安琪拉:Java內(nèi)存模型( Java Memory Model),簡(jiǎn)稱(chēng)JMM, 是 Java 中非常重要的一個(gè)概念,是Java 并發(fā)編程的核心。JMM 是Java 定義的一套協(xié)議,用來(lái)屏蔽各種硬件和操作系統(tǒng)的內(nèi)存訪問(wèn)差異,讓Java 程序在各種平臺(tái)都能有一致的運(yùn)行效果。

面試官:你說(shuō)Java 定義的一套協(xié)議,那既然是協(xié)議,肯定是約定了一些內(nèi)容,這套協(xié)議規(guī)定了什么內(nèi)容?

安琪拉:是的,協(xié)議這個(gè)詞很熟悉,HTTP 協(xié)議、TCP 協(xié)議等。Java內(nèi)存模型(JMM) 協(xié)議定了一套規(guī)范:

所有的變量都存儲(chǔ)在主內(nèi)存中,每個(gè)線程還有自己的工作內(nèi)存,線程的工作內(nèi)存中保存了該線程使用到的變量(主內(nèi)存的拷貝),線程對(duì)變量的所有操作(讀取、賦值)都必須在工作內(nèi)存中進(jìn)行,而不能直接讀寫(xiě)主內(nèi)存中的變量。不同線程之間無(wú)法直接訪問(wèn)對(duì)方工作內(nèi)存中的變量,線程間變量值的傳遞均需要在主內(nèi)存來(lái)完成,如下圖所示,線程的所有操作都是把主內(nèi)存的數(shù)據(jù)放在自己的工作內(nèi)存進(jìn)行。

面試官:你剛才說(shuō)了一大堆概念,能詳細(xì)講講嗎?比如你剛才講的所有變量都在主內(nèi)存中,每個(gè)線程有自己的工作內(nèi)存,能好好講講什么是主內(nèi)存和工作內(nèi)存嗎?

安琪拉:很多人在這里會(huì)有一個(gè)誤區(qū),認(rèn)為主內(nèi)存、工作內(nèi)存是物理的內(nèi)存條中的內(nèi)存,實(shí)際上工作內(nèi)存、主內(nèi)存都是Java內(nèi)存模型中的概念模型。

面試官:那我們上一節(jié)說(shuō)的JVM內(nèi)存區(qū)域劃分,有堆和棧,堆是所有線程共享的,棧是線程私有的,這個(gè)和真實(shí)的物理存儲(chǔ)有什么關(guān)系呢?

安琪拉:這個(gè)問(wèn)題非常棒!JMM 中定義的每個(gè)線程私有的工作內(nèi)存是抽象的規(guī)范,實(shí)際上工作內(nèi)存和真實(shí)的CPU 內(nèi)存架構(gòu)如下所示,Java 內(nèi)存模型和真實(shí)硬件內(nèi)存架構(gòu)是不同的:

JMM與真實(shí)內(nèi)存架構(gòu)

JMM與真實(shí)內(nèi)存架構(gòu)

JMM 是內(nèi)存模型,是抽象的協(xié)議。首先真實(shí)的內(nèi)存架構(gòu)是沒(méi)有區(qū)分堆和棧的,這個(gè)Java 的JVM 來(lái)做的劃分,另外線程私有的本地內(nèi)存線程??赡馨–PU 寄存器、緩存和主存。堆亦是如此!

面試官: 能具體講講JMM 內(nèi)存模型規(guī)范嗎?

安琪拉: 可以。前面已經(jīng)講了線程本地內(nèi)存和物理真實(shí)內(nèi)存之間的關(guān)系,說(shuō)的詳細(xì)些:

初始變量首先存儲(chǔ)在主內(nèi)存中;

線程操作變量需要從主內(nèi)存拷貝到線程本地內(nèi)存中;

線程的本地工作內(nèi)存是一個(gè)抽象概念,包括了緩存、寄存器、store buffer(CPU內(nèi)的緩存區(qū)域)等。

一個(gè)變量如何從主內(nèi)存拷貝到工作內(nèi)存、如何從工作內(nèi)存同步到主內(nèi)存之間的實(shí)現(xiàn)細(xì)節(jié),Java內(nèi)存模型定義了以下八種操作(單一操作都是原子的)來(lái)完成:

  • lock(鎖定):作用于主內(nèi)存的變量,把一個(gè)變量標(biāo)識(shí)為一條線程獨(dú)占狀態(tài)。
  • unlock(解鎖):作用于主內(nèi)存變量,把一個(gè)處于鎖定狀態(tài)的變量解除鎖定,解除鎖定后的變量才可以被其他線程鎖定。
  • read(讀取):作用于主內(nèi)存變量,把一個(gè)變量值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便隨后的load動(dòng)作使用
  • load(載入):作用于工作內(nèi)存的變量,它把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中。
  • use(使用):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個(gè)變量值傳遞給執(zhí)行引擎,每當(dāng)虛擬機(jī)遇到一個(gè)需要使用變量的值的字節(jié)碼指令時(shí)將會(huì)執(zhí)行這個(gè)操作。
  • assign(賦值):作用于工作內(nèi)存的變量,它把一個(gè)從執(zhí)行引擎接收到的值賦值給工作內(nèi)存的變量,每當(dāng)虛擬機(jī)遇到一個(gè)給變量賦值的字節(jié)碼指令時(shí)執(zhí)行這個(gè)操作。
  • store(有的指令是save/存儲(chǔ)):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個(gè)變量的值傳送到主內(nèi)存中,以便隨后的write的操作。
  • write(寫(xiě)入):作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中一個(gè)變量的值傳送到主內(nèi)存的變量中。

Java內(nèi)存模型還規(guī)定了在執(zhí)行上述八種基本操作時(shí),必須滿(mǎn)足如下規(guī)則:

  • 如果要把一個(gè)變量從主內(nèi)存中復(fù)制到工作內(nèi)存,需要順序執(zhí)行read 和load 操作, 如果把變量從工作內(nèi)存中同步回主內(nèi)存中,就要按順序地執(zhí)行store 和write 操作。但Java內(nèi)存模型只要求上述操作必須按順序執(zhí)行,而沒(méi)有保證必須是連續(xù)執(zhí)行,也就是操作不是原子的,一組操作可以中斷。
  • 不允許read和load、store和write操作之一單獨(dú)出現(xiàn),必須成對(duì)出現(xiàn)。
  • 不允許一個(gè)線程丟棄它的最近assign的操作,即變量在工作內(nèi)存中改變了之后必須同步到主內(nèi)存中。
  • 不允許一個(gè)線程無(wú)原因地(沒(méi)有發(fā)生過(guò)任何assign操作)把數(shù)據(jù)從工作內(nèi)存同步回主內(nèi)存中。
  • 一個(gè)新的變量只能在主內(nèi)存中誕生,不允許在工作內(nèi)存中直接使用一個(gè)未被初始化(load或assign)的變量。即就是對(duì)一個(gè)變量實(shí)施use和store操作之前,必須先執(zhí)行過(guò)了assign和load操作。
  • 一個(gè)變量在同一時(shí)刻只允許一條線程對(duì)其進(jìn)行l(wèi)ock操作,但lock操作可以被同一條線程重復(fù)執(zhí)行多次,多次執(zhí)行l(wèi)ock后,只有執(zhí)行相同次數(shù)的unlock操作,變量才會(huì)被解鎖。lock和unlock必須成對(duì)出現(xiàn)
  • 如果對(duì)一個(gè)變量執(zhí)行l(wèi)ock操作,將會(huì)清空工作內(nèi)存中此變量的值,在執(zhí)行引擎使用這個(gè)變量前需要重新執(zhí)行l(wèi)oad或assign操作初始化變量的值
  • 如果一個(gè)變量事先沒(méi)有被lock操作鎖定,則不允許對(duì)它執(zhí)行unlock操作;也不允許去unlock一個(gè)被其他線程鎖定的變量。
  • 對(duì)一個(gè)變量執(zhí)行unlock操作之前,必須先把此變量同步到主內(nèi)存中(執(zhí)行store和write操作)。

面試官: 并發(fā)編程的三個(gè)特征,你知道嗎?

安琪拉: 多線程并發(fā)編程中主要圍繞著三個(gè)特性實(shí)現(xiàn)。

  • 可見(jiàn)性

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

  • 原子性

原子性指的一個(gè)操作或一組操作要么全部執(zhí)行,要么全部不執(zhí)行。

  • 有序性

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

 

主要JMM的內(nèi)容介紹完了,后面再介紹volatile的時(shí)候詳細(xì)說(shuō)lock指令,并發(fā)編程的原子性、可見(jiàn)性、有序性。

 

責(zé)任編輯:武曉燕 來(lái)源: 安琪拉的博客
相關(guān)推薦

2019-08-07 14:52:34

分庫(kù)分表數(shù)據(jù)庫(kù)

2014-08-07 10:03:31

debug技巧原則

2014-08-07 10:49:20

debugdebug技巧

2023-06-19 08:02:40

2021-03-17 08:22:04

JDK16 HotSpot源碼

2013-12-12 16:25:18

微軟Windows 9Threshold

2020-08-31 11:30:06

編程語(yǔ)言

2015-06-01 10:17:36

2023-03-26 11:26:29

2018-12-21 15:29:20

保險(xiǎn)電商職業(yè)

2022-11-16 16:14:46

單踏板模式特斯拉

2019-03-01 15:57:00

服務(wù)器硬件數(shù)據(jù)量

2015-11-10 17:36:18

2018-03-27 09:31:21

數(shù)據(jù)庫(kù)MySQL線程池

2009-03-18 17:53:05

SunIBM收購(gòu)

2018-03-27 23:20:57

互聯(lián)網(wǎng)隱私平臺(tái)

2018-07-04 14:43:55

對(duì)象模型內(nèi)存結(jié)構(gòu)內(nèi)存模型

2009-06-24 16:50:11

Java內(nèi)存模型

2018-07-16 15:05:43

Redis內(nèi)存數(shù)據(jù)庫(kù)

2013-07-11 10:37:20

Java內(nèi)存模型
點(diǎn)贊
收藏

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