摘要:無(wú)論是互斥鎖,還是自旋鎖,在任何時(shí)刻,最多只能有一個(gè)保持者,也就說(shuō),在任何時(shí)刻最多只能有一個(gè)執(zhí)行單元獲得鎖。另外在中引入了自適應(yīng)的自旋鎖。和關(guān)鍵字的總結(jié)推薦一
該文已加入開(kāi)源文檔:JavaGuide(一份涵蓋大部分Java程序員所需要掌握的核心知識(shí))。地址:https://github.com/Snailclimb...
本文是對(duì) synchronized 關(guān)鍵字使用、底層原理、JDK1.6之后的底層優(yōu)化以及和ReenTrantLock對(duì)比做的總結(jié)。如果沒(méi)有學(xué)過(guò) synchronized 關(guān)鍵字使用的話,閱讀起來(lái)可能比較費(fèi)力。兩篇比較基礎(chǔ)的講解 synchronized 關(guān)鍵字的文章:
《Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1)》
《Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(2)》
synchronized 關(guān)鍵字的總結(jié) synchronized關(guān)鍵字最主要的三種使用方式的總結(jié)修飾實(shí)例方法,作用于當(dāng)前對(duì)象實(shí)例加鎖,進(jìn)入同步代碼前要獲得當(dāng)前對(duì)象實(shí)例的鎖
修飾靜態(tài)方法,作用于當(dāng)前類對(duì)象加鎖,進(jìn)入同步代碼前要獲得當(dāng)前類對(duì)象的鎖 。也就是給當(dāng)前類加鎖,會(huì)作用于類的所有對(duì)象實(shí)例,因?yàn)殪o態(tài)成員不屬于任何一個(gè)實(shí)例對(duì)象,是類成員( static 表明這是該類的一個(gè)靜態(tài)資源,不管new了多少個(gè)對(duì)象,只有一份,所以對(duì)該類的所有對(duì)象都加了鎖)。所以如果一個(gè)線程A調(diào)用一個(gè)實(shí)例對(duì)象的非靜態(tài)synchronized 方法,而線程B需要調(diào)用這個(gè)實(shí)例對(duì)象所屬類的靜態(tài) synchronized 方法,是允許的,不會(huì)發(fā)生互斥現(xiàn)象,因?yàn)樵L問(wèn)靜態(tài) synchronized 方法占用的鎖是當(dāng)前類的鎖,而訪問(wèn)非靜態(tài) synchronized 方法占用的鎖是當(dāng)前實(shí)例對(duì)象鎖。
修飾代碼塊,指定加鎖對(duì)象,對(duì)給定對(duì)象加鎖,進(jìn)入同步代碼庫(kù)前要獲得給定對(duì)象的鎖。 和 synchronized 方法一樣,synchronized(this)代碼塊也是鎖定當(dāng)前對(duì)象的。synchronized 關(guān)鍵字加到 static 靜態(tài)方法和 synchronized(class)代碼塊上都是是給 Class 類上鎖。這里再提一下:synchronized關(guān)鍵字加到非 static 靜態(tài)方法上是給對(duì)象實(shí)例上鎖。另外需要注意的是:盡量不要使用 synchronized(String a) 因?yàn)镴VM中,字符串常量池具有緩沖功能!
synchronized 關(guān)鍵字底層實(shí)現(xiàn)原理總結(jié)synchronized 同步語(yǔ)句塊的實(shí)現(xiàn)使用的是 monitorenter 和 monitorexit 指令,其中 monitorenter 指令指向同步代碼塊的開(kāi)始位置,monitorexit 指令則指明同步代碼塊的結(jié)束位置。 當(dāng)執(zhí)行 monitorenter 指令時(shí),線程試圖獲取鎖也就是獲取 monitor(monitor對(duì)象存在于每個(gè)Java對(duì)象的對(duì)象頭中,synchronized 鎖便是通過(guò)這種方式獲取鎖的,也是為什么Java中任意對(duì)象可以作為鎖的原因) 的持有權(quán).當(dāng)計(jì)數(shù)器為0則可以成功獲取,獲取后將鎖計(jì)數(shù)器設(shè)為1也就是加1。相應(yīng)的在執(zhí)行 monitorexit 指令后,將鎖計(jì)數(shù)器設(shè)為0,表明鎖被釋放。如果獲取對(duì)象鎖失敗,那當(dāng)前線程就要阻塞等待,直到鎖被另外一個(gè)線程釋放為止。
synchronized 修飾的方法并沒(méi)有 monitorenter 指令和 monitorexit 指令,取得代之的確實(shí)是 ACC_SYNCHRONIZED 標(biāo)識(shí),該標(biāo)識(shí)指明了該方法是一個(gè)同步方法,JVM 通過(guò)該 ACC_SYNCHRONIZED 訪問(wèn)標(biāo)志來(lái)辨別一個(gè)方法是否聲明為同步方法,從而執(zhí)行相應(yīng)的同步調(diào)用。 在 Java 早期版本中,synchronized 屬于重量級(jí)鎖,效率低下,因?yàn)楸O(jiān)視器鎖(monitor)是依賴于底層的操作系統(tǒng)的Mutex Lock 來(lái)實(shí)現(xiàn)的,Java 的線程是映射到操作系統(tǒng)的原生線程之上的。如果要掛起或者喚醒一個(gè)線程,都需要操作系統(tǒng)幫忙完成,而操作系統(tǒng)實(shí)現(xiàn)線程之間的切換時(shí)需要從用戶態(tài)轉(zhuǎn)換到內(nèi)核態(tài),這個(gè)狀態(tài)之間的轉(zhuǎn)換需要相對(duì)比較長(zhǎng)的時(shí)間,時(shí)間成本相對(duì)較高,這也是為什么早期的 synchronized 效率低的原因。慶幸的是在 Java 6 之后 Java 官方對(duì)從 JVM 層面對(duì)synchronized 較大優(yōu)化,所以現(xiàn)在的 synchronized 鎖效率也優(yōu)化得很不錯(cuò)了。JDK1.6對(duì)鎖的實(shí)現(xiàn)引入了大量的優(yōu)化,如自旋鎖、適應(yīng)性自旋鎖、鎖消除、鎖粗化、偏向鎖、輕量級(jí)鎖等技術(shù)來(lái)減少鎖操作的開(kāi)銷。
所有用戶程序都是運(yùn)行在用戶態(tài)的, 但是有時(shí)候程序確實(shí)需要做一些內(nèi)核態(tài)的事情, 例如從硬盤讀取數(shù)據(jù), 或者從鍵盤獲取輸入等. 而唯一可以做這些事情的就是操作系統(tǒng),synchronized關(guān)鍵字底層優(yōu)化總結(jié)
JDK1.6 對(duì)鎖的實(shí)現(xiàn)引入了大量的優(yōu)化,如自旋鎖、適應(yīng)性自旋鎖、鎖消除、鎖粗化、偏向鎖、輕量級(jí)鎖等技術(shù)來(lái)減少鎖操作的開(kāi)銷。
鎖主要存在四中狀態(tài),依次是:無(wú)鎖狀態(tài)、偏向鎖狀態(tài)、輕量級(jí)鎖狀態(tài)、重量級(jí)鎖狀態(tài),他們會(huì)隨著競(jìng)爭(zhēng)的激烈而逐漸升級(jí)。注意鎖可以升級(jí)不可降級(jí),這種策略是為了提高獲得鎖和釋放鎖的效率。
偏向鎖引入偏向鎖的目的和引入輕量級(jí)鎖的目的很像,他們都是為了沒(méi)有多線程競(jìng)爭(zhēng)的前提下,減少傳統(tǒng)的重量級(jí)鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗。但是不同是:輕量級(jí)鎖在無(wú)競(jìng)爭(zhēng)的情況下使用 CAS 操作去代替使用互斥量。而偏向鎖在無(wú)競(jìng)爭(zhēng)的情況下會(huì)把整個(gè)同步都消除掉。
偏向鎖的“偏”就是偏心的偏,它的意思是會(huì)偏向于第一個(gè)獲得它的線程,如果在接下來(lái)的執(zhí)行中,該鎖沒(méi)有被其他線程獲取,那么持有偏向鎖的線程就不需要進(jìn)行同步!關(guān)于偏向鎖的原理可以查看《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐》第二版的13章第三節(jié)鎖優(yōu)化。
但是對(duì)于鎖競(jìng)爭(zhēng)比較激烈的場(chǎng)合,偏向鎖就失效了,因?yàn)檫@樣場(chǎng)合極有可能每次申請(qǐng)鎖的線程都是不相同的,因此這種場(chǎng)合下不應(yīng)該使用偏向鎖,否則會(huì)得不償失,需要注意的是,偏向鎖失敗后,并不會(huì)立即膨脹為重量級(jí)鎖,而是先升級(jí)為輕量級(jí)鎖。
輕量級(jí)鎖倘若偏向鎖失敗,虛擬機(jī)并不會(huì)立即升級(jí)為重量級(jí)鎖,它還會(huì)嘗試使用一種稱為輕量級(jí)鎖的優(yōu)化手段(1.6之后加入的)。輕量級(jí)鎖不是為了代替重量級(jí)鎖,它的本意是在沒(méi)有多線程競(jìng)爭(zhēng)的前提下,減少傳統(tǒng)的重量級(jí)鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗,因?yàn)槭褂幂p量級(jí)鎖時(shí),不需要申請(qǐng)互斥量。另外,輕量級(jí)鎖的加鎖和解鎖都用到了CAS操作。 關(guān)于輕量級(jí)鎖的加鎖和解鎖的原理可以查看《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐》第二版的13章第三節(jié)鎖優(yōu)化。
輕量級(jí)鎖能夠提升程序同步性能的依據(jù)是“對(duì)于絕大部分鎖,在整個(gè)同步周期內(nèi)都是不存在競(jìng)爭(zhēng)的”,這是一個(gè)經(jīng)驗(yàn)數(shù)據(jù)。如果沒(méi)有競(jìng)爭(zhēng),輕量級(jí)鎖使用 CAS 操作避免了使用互斥操作的開(kāi)銷。但如果存在鎖競(jìng)爭(zhēng),除了互斥量開(kāi)銷外,還會(huì)額外發(fā)生CAS操作,因此在有鎖競(jìng)爭(zhēng)的情況下,輕量級(jí)鎖比傳統(tǒng)的重量級(jí)鎖更慢!如果鎖競(jìng)爭(zhēng)激烈,那么輕量級(jí)將很快膨脹為重量級(jí)鎖!
自旋鎖和自適應(yīng)自旋輕量級(jí)鎖失敗后,虛擬機(jī)為了避免線程真實(shí)地在操作系統(tǒng)層面掛起,還會(huì)進(jìn)行一項(xiàng)稱為自旋鎖的優(yōu)化手段。
互斥同步對(duì)性能最大的影響就是阻塞的實(shí)現(xiàn),因?yàn)閽炱鹁€程/恢復(fù)線程的操作都需要轉(zhuǎn)入內(nèi)核態(tài)中完成(用戶態(tài)轉(zhuǎn)換到內(nèi)核態(tài)會(huì)耗費(fèi)時(shí)間)。
一般線程持有鎖的時(shí)間都不是太長(zhǎng),所以僅僅為了這一點(diǎn)時(shí)間去掛起線程/恢復(fù)線程是得不償失的。 所以,虛擬機(jī)的開(kāi)發(fā)團(tuán)隊(duì)就這樣去考慮:“我們能不能讓后面來(lái)的請(qǐng)求獲取鎖的線程等待一會(huì)而不被掛起呢?看看持有鎖的線程是否很快就會(huì)釋放鎖”。為了讓一個(gè)線程等待,我們只需要讓線程執(zhí)行一個(gè)忙循環(huán)(自旋),這項(xiàng)技術(shù)就叫做自旋。
百度百科對(duì)自旋鎖的解釋:
何謂自旋鎖?它是為實(shí)現(xiàn)保護(hù)共享資源而提出一種鎖機(jī)制。其實(shí),自旋鎖與互斥鎖比較類似,它們都是為了解決對(duì)某項(xiàng)資源的互斥使用。無(wú)論是互斥鎖,還是自旋鎖,在任何時(shí)刻,最多只能有一個(gè)保持者,也就說(shuō),在任何時(shí)刻最多只能有一個(gè)執(zhí)行單元獲得鎖。但是兩者在調(diào)度機(jī)制上略有不同。對(duì)于互斥鎖,如果資源已經(jīng)被占用,資源申請(qǐng)者只能進(jìn)入睡眠狀態(tài)。但是自旋鎖不會(huì)引起調(diào)用者睡眠,如果自旋鎖已經(jīng)被別的執(zhí)行單元保持,調(diào)用者就一直循環(huán)在那里看是否該自旋鎖的保持者已經(jīng)釋放了鎖,"自旋"一詞就是因此而得名。
自旋鎖在 JDK1.6 之前其實(shí)就已經(jīng)引入了,不過(guò)是默認(rèn)關(guān)閉的,需要通過(guò)--XX:+UseSpinning參數(shù)來(lái)開(kāi)啟。JDK1.6及1.6之后,就改為默認(rèn)開(kāi)啟的了。需要注意的是:自旋等待不能完全替代阻塞,因?yàn)樗€是要占用處理器時(shí)間。如果鎖被占用的時(shí)間短,那么效果當(dāng)然就很好了!反之,相反!自旋等待的時(shí)間必須要有限度。如果自旋超過(guò)了限定次數(shù)任然沒(méi)有獲得鎖,就應(yīng)該掛起線程。自旋次數(shù)的默認(rèn)值是10次,用戶可以修改--XX:PreBlockSpin來(lái)更改。
另外,在 JDK1.6 中引入了自適應(yīng)的自旋鎖。自適應(yīng)的自旋鎖帶來(lái)的改進(jìn)就是:自旋的時(shí)間不在固定了,而是和前一次同一個(gè)鎖上的自旋時(shí)間以及鎖的擁有者的狀態(tài)來(lái)決定,虛擬機(jī)變得越來(lái)越“聰明”了。
鎖消除鎖消除理解起來(lái)很簡(jiǎn)單,它指的就是虛擬機(jī)即使編譯器在運(yùn)行時(shí),如果檢測(cè)到那些共享數(shù)據(jù)不可能存在競(jìng)爭(zhēng),那么就執(zhí)行鎖消除。鎖消除可以節(jié)省毫無(wú)意義的請(qǐng)求鎖的時(shí)間。
鎖粗化原則上,我們?cè)倬帉懘a的時(shí)候,總是推薦將同步快的作用范圍限制得盡量小——只在共享數(shù)據(jù)的實(shí)際作用域才進(jìn)行同步,這樣是為了使得需要同步的操作數(shù)量盡可能變小,如果存在鎖競(jìng)爭(zhēng),那等待線程也能盡快拿到鎖。
大部分情況下,上面的原則都是沒(méi)有問(wèn)題的,但是如果一系列的連續(xù)操作都對(duì)同一個(gè)對(duì)象反復(fù)加鎖和解鎖,那么會(huì)帶來(lái)很多不必要的性能消耗。
ReenTrantLock 和 synchronized 關(guān)鍵字的總結(jié)推薦一篇講解 ReenTrantLock 的使用比較基礎(chǔ)的文章:《Java多線程學(xué)習(xí)(六)Lock鎖的使用》
兩者都是可重入鎖兩者都是可重入鎖?!翱芍厝腈i”概念是:自己可以再次獲取自己的內(nèi)部鎖。比如一個(gè)線程獲得了某個(gè)對(duì)象的鎖,此時(shí)這個(gè)對(duì)象鎖還沒(méi)有釋放,當(dāng)其再次想要獲取這個(gè)對(duì)象的鎖的時(shí)候還是可以獲取的,如果不可鎖重入的話,就會(huì)造成死鎖。同一個(gè)線程每次獲取鎖,鎖的計(jì)數(shù)器都自增1,所以要等到鎖的計(jì)數(shù)器下降為0時(shí)才能釋放鎖。
synchronized 依賴于 JVM 而 ReenTrantLock 依賴于 APIsynchronized 是依賴于 JVM 實(shí)現(xiàn)的,前面我們也講到了 虛擬機(jī)團(tuán)隊(duì)在 JDK1.6 為 synchronized 關(guān)鍵字進(jìn)行了很多優(yōu)化,但是這些優(yōu)化都是在虛擬機(jī)層面實(shí)現(xiàn)的,并沒(méi)有直接暴露給我們。ReenTrantLock 是 JDK 層面實(shí)現(xiàn)的(也就是 API 層面,需要 lock() 和 unlock 方法配合 try/finally 語(yǔ)句塊來(lái)完成),所以我們可以通過(guò)查看它的源代碼,來(lái)看它是如何實(shí)現(xiàn)的。
ReenTrantLock 比 synchronized 增加了一些高級(jí)功能相比synchronized,ReenTrantLock增加了一些高級(jí)功能。主要來(lái)說(shuō)主要有三點(diǎn):①等待可中斷;②可實(shí)現(xiàn)公平鎖;③可實(shí)現(xiàn)選擇性通知(鎖可以綁定多個(gè)條件)
ReenTrantLock提供了一種能夠中斷等待鎖的線程的機(jī)制,通過(guò)lock.lockInterruptibly()來(lái)實(shí)現(xiàn)這個(gè)機(jī)制。也就是說(shuō)正在等待的線程可以選擇放棄等待,改為處理其他事情。
ReenTrantLock可以指定是公平鎖還是非公平鎖。而synchronized只能是非公平鎖。所謂的公平鎖就是先等待的線程先獲得鎖。 ReenTrantLock默認(rèn)情況是非公平的,可以通過(guò) ReenTrantLock類的ReentrantLock(boolean fair)構(gòu)造方法來(lái)制定是否是公平的。
synchronized關(guān)鍵字與wait()和notify/notifyAll()方法相結(jié)合可以實(shí)現(xiàn)等待/通知機(jī)制,ReentrantLock類當(dāng)然也可以實(shí)現(xiàn),但是需要借助于Condition接口與newCondition() 方法。Condition是JDK1.5之后才有的,它具有很好的靈活性,比如可以實(shí)現(xiàn)多路通知功能也就是在一個(gè)Lock對(duì)象中可以創(chuàng)建多個(gè)Condition實(shí)例(即對(duì)象監(jiān)視器),線程對(duì)象可以注冊(cè)在指定的Condition中,從而可以有選擇性的進(jìn)行線程通知,在調(diào)度線程上更加靈活。 在使用notify/notifyAll()方法進(jìn)行通知時(shí),被通知的線程是由 JVM 選擇的,用ReentrantLock類結(jié)合Condition實(shí)例可以實(shí)現(xiàn)“選擇性通知” ,這個(gè)功能非常重要,而且是Condition接口默認(rèn)提供的。而synchronized關(guān)鍵字就相當(dāng)于整個(gè)Lock對(duì)象中只有一個(gè)Condition實(shí)例,所有的線程都注冊(cè)在它一個(gè)身上。如果執(zhí)行notifyAll()方法的話就會(huì)通知所有處于等待狀態(tài)的線程這樣會(huì)造成很大的效率問(wèn)題,而Condition實(shí)例的signalAll()方法 只會(huì)喚醒注冊(cè)在該Condition實(shí)例中的所有等待線程。
如果你想使用上述功能,那么選擇ReenTrantLock是一個(gè)不錯(cuò)的選擇。
性能已不是選擇標(biāo)準(zhǔn)在JDK1.6之前,synchronized 的性能是比 ReenTrantLock 差很多。具體表示為:synchronized 關(guān)鍵字吞吐量歲線程數(shù)的增加,下降得非常嚴(yán)重。而ReenTrantLock 基本保持一個(gè)比較穩(wěn)定的水平。我覺(jué)得這也側(cè)面反映了, synchronized 關(guān)鍵字還有非常大的優(yōu)化余地。后續(xù)的技術(shù)發(fā)展也證明了這一點(diǎn),我們上面也講了在 JDK1.6 之后 JVM 團(tuán)隊(duì)對(duì) synchronized 關(guān)鍵字做了很多優(yōu)化。JDK1.6 之后,synchronized 和 ReenTrantLock 的性能基本是持平了。所以網(wǎng)上那些說(shuō)因?yàn)樾阅懿胚x擇 ReenTrantLock 的文章都是錯(cuò)的!JDK1.6之后,性能已經(jīng)不是選擇synchronized和ReenTrantLock的影響因素了!而且虛擬機(jī)在未來(lái)的性能改進(jìn)中會(huì)更偏向于原生的synchronized,所以還是提倡在synchronized能滿足你的需求的情況下,優(yōu)先考慮使用synchronized關(guān)鍵字來(lái)進(jìn)行同步!優(yōu)化后的synchronized和ReenTrantLock一樣,在很多地方都是用到了CAS操作。
參考《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐》第二版第13章
《實(shí)戰(zhàn)Java虛擬機(jī)》
https://blog.csdn.net/javazej...
https://blog.csdn.net/qq83864...
http://cmsblogs.com/?p=2071
你若盛開(kāi),清風(fēng)自來(lái)。 歡迎關(guān)注我的微信公眾號(hào):“Java面試通關(guān)手冊(cè)”,一個(gè)有溫度的微信公眾號(hào)。公眾號(hào)后臺(tái)回復(fù)關(guān)鍵字“1”,你可能看到想要的東西哦!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/77003.html
摘要:死亡狀態(tài)線程退出有可能是正常執(zhí)行完成也有可能遇見(jiàn)異常退出。類有新建與死亡狀態(tài)返回其余狀態(tài)返回判斷線程是否存活。線程因某些原因進(jìn)入阻塞狀態(tài)。執(zhí)行同步代碼塊的過(guò)程中執(zhí)行了當(dāng)前線程放棄開(kāi)始睡眠進(jìn)入就緒狀態(tài)但是不會(huì)釋放鎖。 【java內(nèi)存模型簡(jiǎn)介 JVM中存在一個(gè)主存區(qū)(Main Memory或Java Heap Memory),Java中所有變量都是存在主存中的,對(duì)于所有線程進(jìn)行共享,而每個(gè)...
摘要:當(dāng)其他線程調(diào)用時(shí),它們被阻塞,直到第一個(gè)線程釋放鎖對(duì)象。包關(guān)于獲取這個(gè)鎖如果鎖同時(shí)被另一個(gè)線程擁有則發(fā)生阻塞。所以必須確保沒(méi)有其他線程再檢查余額和轉(zhuǎn)賬活動(dòng)之間修改金額。方法添加一個(gè)線程到等待集中,方法解除等待線程的阻塞狀態(tài)。 避免代碼塊受到并發(fā)訪問(wèn)的干擾 java語(yǔ)言提供了兩種機(jī)制實(shí)現(xiàn)這種功能 Synchonized 關(guān)鍵字(調(diào)用對(duì)象內(nèi)部的鎖) synchronized關(guān)鍵字自動(dòng)...
摘要:阿里開(kāi)始招實(shí)習(xí),同學(xué)問(wèn)我要不要去申請(qǐng)阿里的實(shí)習(xí),我說(shuō)不去,個(gè)人對(duì)阿里的印象不好。記得去年阿里給我發(fā)了郵件,我很認(rèn)真地回復(fù),然后他不理我了。 引言 最近好久沒(méi)有遇到技術(shù)瓶頸了,思考得自然少了,每天都是重復(fù)性的工作。 阿里開(kāi)始招實(shí)習(xí),同學(xué)問(wèn)我要不要去申請(qǐng)阿里的實(shí)習(xí),我說(shuō)不去,個(gè)人對(duì)阿里的印象不好。 記得去年阿里給我發(fā)了郵件,我很認(rèn)真地回復(fù),然后他不理我了。(最起碼的尊重都沒(méi)有,就算我菜你起...
摘要:所以多線程條件下使用關(guān)鍵字的前提是對(duì)變量的寫操作不依賴于變量的當(dāng)前值,而賦值操作很明顯滿足這一前提。在多線程環(huán)境下,正確使用關(guān)鍵字可以比直接使用更加高效而且代碼簡(jiǎn)潔,但是使用關(guān)鍵字也更容易出錯(cuò)。 volatile 作為 Java 語(yǔ)言的一個(gè)關(guān)鍵字,被看作是輕量級(jí)的 synchronized(鎖)。雖然 volatile 只具有synchronized 的部分功能,但是一般使用 vola...
時(shí)間:2017年07月09日星期日說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:無(wú)學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:課程簡(jiǎn)介 1-1 課程簡(jiǎn)介 課程目標(biāo)和學(xué)習(xí)內(nèi)容 共享變量在線程間的可見(jiàn)性 synchronized實(shí)現(xiàn)可見(jiàn)性 volatile實(shí)現(xiàn)可見(jiàn)性 指令重排序 as-if-seria...
閱讀 736·2025-02-07 13:40
閱讀 1050·2025-02-07 13:37
閱讀 1104·2024-11-06 13:38
閱讀 1194·2024-09-10 13:19
閱讀 1312·2024-08-22 19:45
閱讀 1492·2021-11-19 09:40
閱讀 2845·2021-11-18 13:14
閱讀 4422·2021-10-09 10:02