java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?
轉(zhuǎn)載自?java多線程中的死鎖、活鎖、饑餓、無(wú)鎖都是什么鬼?
死鎖、活鎖、饑餓是關(guān)于多線程是否活躍出現(xiàn)的運(yùn)行阻塞障礙問(wèn)題,如果線程出現(xiàn)了這三種情況,即線程不再活躍,不能再正常地執(zhí)行下去了。
死鎖
死鎖是多線程中最差的一種情況,多個(gè)線程相互占用對(duì)方的資源的鎖,而又相互等對(duì)方釋放鎖,此時(shí)若無(wú)外力干預(yù),這些線程則一直處理阻塞的假死狀態(tài),形成死鎖。
舉個(gè)例子,A同學(xué)搶了B同學(xué)的鋼筆,B同學(xué)搶了A同學(xué)的書(shū),兩個(gè)人都相互占用對(duì)方的東西,都在讓對(duì)方先還給自己自己再還,這樣一直爭(zhēng)執(zhí)下去等待對(duì)方還而又得不到解決,老師知道此事后就讓他們相互還給對(duì)方,這樣在外力的干預(yù)下他們才解決,當(dāng)然這只是個(gè)例子沒(méi)有老師他們也能很好解決,計(jì)算機(jī)不像人如果發(fā)現(xiàn)這種情況沒(méi)有外力干預(yù)還是會(huì)一直阻塞下去的。
活鎖
活鎖這個(gè)概念大家應(yīng)該很少有人聽(tīng)說(shuō)或理解它的概念,而在多線程中這確實(shí)存在。活鎖恰恰與死鎖相反,死鎖是大家都拿不到資源都占用著對(duì)方的資源,而活鎖是拿到資源卻又相互釋放不執(zhí)行。當(dāng)多線程中出現(xiàn)了相互謙讓,都主動(dòng)將資源釋放給別的線程使用,這樣這個(gè)資源在多個(gè)線程之間跳動(dòng)而又得不到執(zhí)行,這就是活鎖。
饑餓
我們知道多線程執(zhí)行中有線程優(yōu)先級(jí)這個(gè)東西,優(yōu)先級(jí)高的線程能夠插隊(duì)并優(yōu)先執(zhí)行,這樣如果優(yōu)先級(jí)高的線程一直搶占優(yōu)先級(jí)低線程的資源,導(dǎo)致低優(yōu)先級(jí)線程無(wú)法得到執(zhí)行,這就是饑餓。當(dāng)然還有一種饑餓的情況,一個(gè)線程一直占著一個(gè)資源不放而導(dǎo)致其他線程得不到執(zhí)行,與死鎖不同的是饑餓在以后一段時(shí)間內(nèi)還是能夠得到執(zhí)行的,如那個(gè)占用資源的線程結(jié)束了并釋放了資源。
無(wú)鎖
無(wú)鎖,即沒(méi)有對(duì)資源進(jìn)行鎖定,即所有的線程都能訪問(wèn)并修改同一個(gè)資源,但同時(shí)只有一個(gè)線程能修改成功。無(wú)鎖典型的特點(diǎn)就是一個(gè)修改操作在一個(gè)循環(huán)內(nèi)進(jìn)行,線程會(huì)不斷的嘗試修改共享資源,如果沒(méi)有沖突就修改成功并退出否則就會(huì)繼續(xù)下一次循環(huán)嘗試。所以,如果有多個(gè)線程修改同一個(gè)值必定會(huì)有一個(gè)線程能修改成功,而其他修改失敗的線程會(huì)不斷重試直到修改成功。之前的文章我介紹過(guò)JDK的CAS原理及應(yīng)用即是無(wú)鎖的實(shí)現(xiàn)。
可以看出,無(wú)鎖是一種非常良好的設(shè)計(jì),它不會(huì)出現(xiàn)線程出現(xiàn)的跳躍性問(wèn)題,鎖使用不當(dāng)肯定會(huì)出現(xiàn)系統(tǒng)性能問(wèn)題,雖然無(wú)鎖無(wú)法全面代替有鎖,但無(wú)鎖在某些場(chǎng)合下是非常高效的。
總結(jié)
以上是生活随笔為你收集整理的java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 已经有域名 怎么修改网站(已经有域名 怎
- 下一篇: 高级java必须清楚的概念:原子性、可见