溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java中volatile和synchronized區(qū)別是什么?

發(fā)布時(shí)間:2020-06-23 15:11:15 來(lái)源:億速云 閱讀:180 作者:清晨 欄目:編程語(yǔ)言

不懂Java中volatile和synchronized區(qū)別是什么??其實(shí)想解決這個(gè)問(wèn)題也不難,下面讓小編帶著大家一起學(xué)習(xí)怎么去解決,希望大家閱讀完這篇文章后大所收獲。

volatile是變量修飾符,而synchronized則是作用于一段代碼或方法;如下三句get代碼:

int i1;
int geti1() {return i1;}

volatile int i2;
int geti2() {return i2;}

int i3;
synchronized int geti3() {return i3;}

geti1() 得到存儲(chǔ)在當(dāng)前線程中i1的數(shù)值。多個(gè)線程有多個(gè)i1變量拷貝,而且這些i1之間可以相互不同。換句話說(shuō),另一個(gè)線程可能已經(jīng)改變了它線程內(nèi)的i1值,而這個(gè)值可以和當(dāng)前線程中的i1值不相同。 在Java內(nèi)存模型中,有main memory(主內(nèi)存區(qū)域),這里存放了變量目前的“準(zhǔn)確值”,每個(gè)線程也有自己的memory(例如寄存器)。為了性能,一個(gè)線程會(huì)在自己的memory中保存要訪問(wèn)的變量的副本。這樣就會(huì)出現(xiàn)同一個(gè)變量在某個(gè)瞬間,在一個(gè)線程的memory中的值可能與另外一個(gè)線程memory的值,或者main memory的值不一致的情況。因此實(shí)際上存在一種可能:main memory的值i1值是1,線程1里的i1是2,線程2里的i1值是3,這在線程1和線程2都改變了他們各自的i1值,而且這個(gè)改變還沒(méi)來(lái)得及傳給main memory 或其他線程時(shí)就會(huì)發(fā)生。

geti2() 得到的是main memory的i2數(shù)值。一個(gè)變量聲明為volatile,就意味著這個(gè)變量是隨時(shí)會(huì)被其他線程修改的,因此不能將它c(diǎn)ache在線程memory中。換句話說(shuō),一個(gè)變量經(jīng)過(guò)volatile修飾后在所有線程中必須是同步的,任何線程中改變了它的值,所有其他線程立即獲得了相同的值。所以,volatile修飾的變量存取時(shí)比一般變量消耗的資源要多一點(diǎn),因?yàn)榫€程有它自己的變量拷貝更為高效。

geti3()方法被synchronized修飾,用synchronized來(lái)修飾一個(gè)方法或者一個(gè)貸款的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。既然volatile關(guān)鍵字已經(jīng)實(shí)現(xiàn)了線程間數(shù)據(jù)同步,又要synchronized干嘛呢?當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步貸款時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊才能執(zhí)行該代碼塊。然而,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問(wèn)該object中的非synchronized(this)同步代碼塊。尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí)候,其他線程對(duì)object中所有其他synchronized(this)同步代碼塊的訪問(wèn)將被阻塞。當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖,結(jié)果,其他線程對(duì)該對(duì)象所有同步代碼部分的訪問(wèn)都被暫時(shí)阻塞。

區(qū)別:

一,volatile是變量修飾符,而synchronized則作用于一段代碼或者方法。

二,volatile只是在線程內(nèi)存和main memory(主內(nèi)存)間同步某個(gè)變量的值;而synchronized通過(guò)鎖定和解鎖某個(gè)監(jiān)視器同步所有變量的值。顯然synchronized要比volatile消耗更多資源。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享Java中volatile和synchronized區(qū)別是什么??jī)?nèi)容對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,遇到問(wèn)題就找億速云,詳細(xì)的解決方法等著你來(lái)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI