成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

JAVA多線程機(jī)制解析-volatile&synchronized

dendoink / 1956人閱讀

摘要:當(dāng)一個(gè)線程持有重量級(jí)鎖時(shí),另外一個(gè)線程就會(huì)被直接踢到同步隊(duì)列中等待。

java代碼先編譯成字節(jié)碼,字節(jié)碼最后編譯成cpu指令,因此Java的多線程實(shí)現(xiàn)最終依賴(lài)于jvm和cpu的實(shí)現(xiàn)

synchronized和volatile

我們先來(lái)討論一下volatile關(guān)鍵字的作用以及實(shí)現(xiàn)機(jī)制,每個(gè)線程看到的用volatile修飾的變量的值都是最新的,更深入的解釋就涉及到Java的內(nèi)存模型了,我們知道Java將內(nèi)存分為主內(nèi)存和線程私有內(nèi)存,所有的全局變量都在主內(nèi)存中,每個(gè)線程使用變量時(shí)都會(huì)從主內(nèi)存中讀取變量,然后放到各自線程的私有內(nèi)存中,這樣線程使用變量時(shí)就不用每次都去讀取主內(nèi)存了,當(dāng)然這也產(chǎn)生了一個(gè)問(wèn)題,如果線程修改了變量值,但是修改的值沒(méi)有及時(shí)地同步到主內(nèi)存中,那么其他線程看到的變量值仍然是未修改之前的值,這就產(chǎn)生了并發(fā)問(wèn)題,而當(dāng)這個(gè)變量用volatile修飾后,每次線程都會(huì)從主內(nèi)存中讀取變量值,也就是說(shuō)拋棄了線程私有內(nèi)存中的變量值,而線程每次修改變量后,就會(huì)將修改后的值同步到主內(nèi)存中去。

理論上volatile就是這么實(shí)現(xiàn)滴,但是volatile最終會(huì)被編譯成機(jī)器指令,所以volatile這種機(jī)制也需要相關(guān)的機(jī)器指令支持,學(xué)習(xí)過(guò)計(jì)算機(jī)組成原理的同學(xué)們都知道計(jì)算機(jī)在cpu和主內(nèi)存直接有一個(gè)cache緩存,是不是和Java模型很類(lèi)似,當(dāng)然還不一樣,其實(shí)volatile最終使用了cpu緩存一致性也就是說(shuō)將緩存中的內(nèi)容立刻更新到主內(nèi)存中去,同時(shí)將其他緩存中的值置為無(wú)效。如果大家有探索精神可以看看看看volatile被編程為的匯編代碼,就會(huì)發(fā)現(xiàn)volatile是用Lock信號(hào)實(shí)現(xiàn)地。

下面我們?cè)賮?lái)說(shuō)說(shuō)synchronized關(guān)鍵字,學(xué)習(xí)過(guò)Java的同學(xué)應(yīng)該都知道這個(gè)關(guān)鍵字是用來(lái)實(shí)現(xiàn)多線程同步的,synchronized的具體用法這里就不介紹了,我們來(lái)聊下這個(gè)關(guān)鍵字的具體實(shí)現(xiàn),看過(guò)Java并發(fā)的同學(xué)都會(huì)發(fā)現(xiàn)synchronized被稱(chēng)為重量級(jí)鎖,怎么理解這個(gè)重量級(jí)的概念那?反正我的理解是加鎖解鎖耗費(fèi)地時(shí)間多,導(dǎo)致并發(fā)度比較低唄,但是隨著JDK版本的升級(jí),synchronized的性能和并發(fā)庫(kù)中Lock的性能基本持平。好了言歸正傳,synchronized的具體實(shí)現(xiàn)不知道同學(xué)們了解多少,我想大部分人應(yīng)該能說(shuō)出synchronized由一個(gè)同步隊(duì)列和對(duì)象監(jiān)視器實(shí)現(xiàn),線程進(jìn)入同步塊時(shí),先獲取監(jiān)視器如果成功就進(jìn)入同步塊,如果不成功就進(jìn)入同步隊(duì)列等待另外一個(gè)線程從同步塊退出,沒(méi)錯(cuò)這就是synchronized的實(shí)現(xiàn),如果你只知道這些說(shuō)明你了解的還不夠深入,因?yàn)槟氵€需要知道偏向鎖、輕量級(jí)鎖和synchronized的關(guān)系,在這里我就拋磚引玉先說(shuō)說(shuō)我自己的理解吧,我們都知道一個(gè)Java對(duì)象有三部分組成,對(duì)象頭,實(shí)體部分,對(duì)齊填充部分,這個(gè)對(duì)象頭就是實(shí)現(xiàn)synchronized的關(guān)鍵,在比較老的JDK版本中,一個(gè)線程進(jìn)入同步代碼塊時(shí)就要獲取互斥量,不管有沒(méi)有其他線程,改進(jìn)后的synchronized,線程一般先獲取偏向鎖,如果有競(jìng)爭(zhēng)就膨脹為輕量級(jí)鎖或者重量級(jí)鎖,輕量級(jí)鎖又會(huì)膨脹為重量級(jí)鎖,那么偏向鎖、輕量級(jí)鎖、重量級(jí)鎖有什么區(qū)別那?

偏向鎖:

對(duì)象頭中設(shè)置偏向鎖標(biāo)記,同時(shí)將當(dāng)前線程的線程id保存在對(duì)象頭和棧的鎖記錄空間中;

輕量級(jí)鎖

將對(duì)象頭的內(nèi)容復(fù)制到當(dāng)前線程棧的鎖記錄空間中,同時(shí)將對(duì)象頭設(shè)置為指向鎖記錄空間的指針;

重量級(jí)鎖
將對(duì)象頭的內(nèi)容復(fù)制到當(dāng)前線程的鎖記錄空間中,同時(shí)將對(duì)象頭設(shè)置為指向互斥量的指針;

當(dāng)一個(gè)線程進(jìn)入同步快時(shí),先通過(guò)cas設(shè)置對(duì)象頭為偏向鎖,若設(shè)置成功則說(shuō)明線程獲取鎖,若設(shè)置不成功,說(shuō)明鎖存在競(jìng)爭(zhēng),持有偏向鎖的線程就要釋放偏向鎖,偏向鎖膨脹為輕量級(jí)鎖或重量級(jí)鎖。
當(dāng)一個(gè)線程持有輕量級(jí)鎖,另外一個(gè)線程嘗試獲取鎖,獲取失敗,則另外一個(gè)線程會(huì)自旋等待,若等待一段時(shí)間仍未獲取鎖,則線程進(jìn)入等待,持有輕量級(jí)鎖的線程就會(huì)在安全點(diǎn)處釋放輕量級(jí)鎖,輕量級(jí)鎖也會(huì)膨脹為重量級(jí)鎖。
當(dāng)一個(gè)線程持有重量級(jí)鎖時(shí),另外一個(gè)線程就會(huì)被直接踢到同步隊(duì)列中等待。

(安全點(diǎn)是jvm的一些特殊位置,在這個(gè)位置上所有的線程都會(huì)暫停工作,一般在安全點(diǎn)處進(jìn)行垃圾回收,還有一個(gè)概念是安全區(qū)域,安全區(qū)域是指在一塊代碼內(nèi)引用關(guān)系不會(huì)發(fā)生變化,這個(gè)代碼的任何位置進(jìn)行垃圾回收都是可以的)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/71036.html

相關(guān)文章

  • Java線程&高并發(fā)

    摘要:線程啟動(dòng)規(guī)則對(duì)象的方法先行發(fā)生于此線程的每一個(gè)動(dòng)作。所以局部變量是不被多個(gè)線程所共享的,也就不會(huì)出現(xiàn)并發(fā)問(wèn)題。通過(guò)獲取到數(shù)據(jù),放入當(dāng)前線程處理完之后將當(dāng)前線程中的信息移除。主線程必須在啟動(dòng)其他線程后立即調(diào)用方法。 一、線程安全性 定義:當(dāng)多個(gè)線程訪問(wèn)某個(gè)類(lèi)時(shí),不管運(yùn)行時(shí)環(huán)境采用何種調(diào)度方式,或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)同,這個(gè)類(lèi)都能表現(xiàn)出正確的行...

    SQC 評(píng)論0 收藏0
  • 深入理解 Java 線程系列(1)——一個(gè)簡(jiǎn)單需求的并行改造 & Java線程的通信問(wèn)題

    摘要:所以接下來(lái),我們需要簡(jiǎn)單的介紹下多線程中的并發(fā)通信模型。比如中,以及各種鎖機(jī)制,均為了解決線程間公共狀態(tài)的串行訪問(wèn)問(wèn)題。 并發(fā)的學(xué)習(xí)門(mén)檻較高,相較單純的羅列并發(fā)編程 API 的枯燥被動(dòng)學(xué)習(xí)方式,本系列文章試圖用一個(gè)簡(jiǎn)單的栗子,一步步結(jié)合并發(fā)編程的相關(guān)知識(shí)分析舊有實(shí)現(xiàn)的不足,再實(shí)現(xiàn)邏輯進(jìn)行分析改進(jìn),試圖展示例子背后的并發(fā)工具與實(shí)現(xiàn)原理。 本文是本系列的第一篇文章,提出了一個(gè)簡(jiǎn)單的業(yè)務(wù)場(chǎng)景...

    ruicbAndroid 評(píng)論0 收藏0
  • 線程學(xué)習(xí)筆記(1):volatilesynchronized

    摘要:今天開(kāi)始整理學(xué)習(xí)多線程的知識(shí),談?wù)勛钪匾膬蓚€(gè)關(guān)鍵字和。但是這樣一個(gè)過(guò)程比較慢,在使用多線程的時(shí)候就會(huì)出現(xiàn)問(wèn)題。有序性有序性是指多線程執(zhí)行結(jié)果的正確性。這種機(jī)制在多線程中會(huì)出現(xiàn)問(wèn)題,因此可以通過(guò)來(lái)禁止重排。 今天開(kāi)始整理學(xué)習(xí)多線程的知識(shí),談?wù)勛钪匾膬蓚€(gè)關(guān)鍵字:volatile和synchronized。 一、三個(gè)特性 1、原子性 所謂原子性操作就是指這些操作是不可中斷的,要么執(zhí)行過(guò)程...

    jk_v1 評(píng)論0 收藏0
  • BATJ都愛(ài)問(wèn)的線程面試題

    摘要:今天給大家總結(jié)一下,面試中出鏡率很高的幾個(gè)多線程面試題,希望對(duì)大家學(xué)習(xí)和面試都能有所幫助。指令重排在單線程環(huán)境下不會(huì)出先問(wèn)題,但是在多線程環(huán)境下會(huì)導(dǎo)致一個(gè)線程獲得還沒(méi)有初始化的實(shí)例。使用可以禁止的指令重排,保證在多線程環(huán)境下也能正常運(yùn)行。 下面最近發(fā)的一些并發(fā)編程的文章匯總,通過(guò)閱讀這些文章大家再看大廠面試中的并發(fā)編程問(wèn)題就沒(méi)有那么頭疼了。今天給大家總結(jié)一下,面試中出鏡率很高的幾個(gè)多線...

    高勝山 評(píng)論0 收藏0
  • Java - 并發(fā) atomic, synchronization and volatile

    摘要:線程的這種交叉操作會(huì)導(dǎo)致線程不安全。原子操作是在多線程環(huán)境下避免數(shù)據(jù)不一致必須的手段。如果聲明一個(gè)域?yàn)橐恍┣闆r就可以確保多線程訪問(wèn)到的變量是最新的。并發(fā)要求一個(gè)線程對(duì)對(duì)象進(jìn)行了操作,對(duì)象發(fā)生了變化,這種變化應(yīng)該對(duì)其他線程是可見(jiàn)的。 雖是讀書(shū)筆記,但是如轉(zhuǎn)載請(qǐng)注明出處 http://segmentfault.com/blog/exploring/ .. 拒絕伸手復(fù)制黨 一個(gè)問(wèn)題: ...

    StonePanda 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

dendoink

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<