摘要:不剝奪條件進(jìn)程已獲得的資源,在末使用完之前,不能強(qiáng)行剝奪。如果能確保所有的線程都是按照相同的順序獲得鎖,那么死鎖就不會(huì)發(fā)生。按照順序加鎖是一種有效的死鎖預(yù)防機(jī)制。這種機(jī)制存在一個(gè)問題,在中不能對(duì)同步塊設(shè)置超時(shí)時(shí)間。
[tutorial site][1]
死鎖 deadlock死鎖是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過程中,因競爭資源而造成的一種互相等待的現(xiàn)在,若無外力作用,它們都無法推進(jìn)下去。
再重提下競態(tài)條件
競態(tài)條件(race condition),從多線程間通信的角度來講,是指兩個(gè)或多個(gè)線程對(duì)共享的數(shù)據(jù)進(jìn)行讀或?qū)懙牟僮鲿r(shí),最終的結(jié)果取決于這些線程的執(zhí)行順序的情況。
導(dǎo)致競態(tài)條件的代碼是關(guān)鍵區(qū)域
這是一個(gè)嚴(yán)重的問題,因?yàn)樗梨i會(huì)讓你的程序掛起無法完成任務(wù),死鎖的發(fā)生必須滿足以下四個(gè)條件:
互斥條件:一個(gè)資源每次只能被一個(gè)進(jìn)程使用。
請(qǐng)求與保持條件:一個(gè)進(jìn)程因請(qǐng)求資源而阻塞時(shí),對(duì)已獲得的資源保持不放。
不剝奪條件:進(jìn)程已獲得的資源,在末使用完之前,不能強(qiáng)行剝奪。
循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
避免死鎖的方法: 加鎖順序當(dāng)多個(gè)線程需要相同的一些鎖,但是按照不同的順序加鎖,死鎖就很容易發(fā)生。
如果能確保所有的線程都是按照相同的順序獲得鎖,那么死鎖就不會(huì)發(fā)生。
Note: 按照順序加鎖是一種有效的死鎖預(yù)防機(jī)制。但是,這種方式需要你事先知道所有可能會(huì)用到的鎖, 并對(duì)這些鎖做適當(dāng)?shù)呐判?,但總有些時(shí)候是無法預(yù)知的.
加鎖時(shí)限另外一個(gè)可以避免死鎖的方法是在嘗試獲取鎖的時(shí)候加一個(gè)超時(shí)時(shí)間,這也就意味著在嘗試獲取鎖的過程中若超過了這個(gè)時(shí)限該線程則放棄對(duì)該鎖請(qǐng)求。若一個(gè)線程沒有在給定的時(shí)限內(nèi)成功獲得所有需要的鎖,則會(huì)進(jìn)行回退并釋放所有已經(jīng)獲得的鎖,然后等待一段隨機(jī)的時(shí)間再重試。這段隨機(jī)的等待時(shí)間讓其它線程有機(jī)會(huì)嘗試獲取相同的這些鎖,并且讓該應(yīng)用在沒有獲得鎖的時(shí)候可以繼續(xù)運(yùn)行.
Note: 由于存在鎖的超時(shí),所以我們不能認(rèn)為這種場景就一定是出現(xiàn)了死鎖。也可能是因?yàn)楂@得了鎖的線程(導(dǎo)致其它線程超時(shí))需要很長的時(shí)間去完成它的任務(wù)。
此外,如果有非常多的線程同一時(shí)間去競爭同一批資源,就算有超時(shí)和回退機(jī)制,還是可能會(huì)導(dǎo)致這些線程重復(fù)地嘗試但卻始終得不到鎖。
這種機(jī)制存在一個(gè)問題,在 Java 中不能對(duì) synchronized 同步塊設(shè)置超時(shí)時(shí)間。你需要?jiǎng)?chuàng)建一個(gè)自定義鎖
死鎖檢測死鎖檢測是一個(gè)更好的死鎖預(yù)防機(jī)制,它主要是針對(duì)那些不可能實(shí)現(xiàn)按序加鎖并且鎖超時(shí)也不可行的場景。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64367.html
摘要:請(qǐng)參看前一篇文章并發(fā)學(xué)習(xí)筆記一原子性可見性有序性問題六等待通知機(jī)制什么是等待通知機(jī)制當(dāng)線程不滿足某個(gè)條件,則進(jìn)入等待狀態(tài)如果線程滿足要求的某個(gè)條件后,則通知等待的線程重新執(zhí)行。經(jīng)極客時(shí)間并發(fā)編程實(shí)戰(zhàn)專欄內(nèi)容學(xué)習(xí)整理 請(qǐng)參看前一篇文章:Java 并發(fā)學(xué)習(xí)筆記(一)——原子性、可見性、有序性問題 六、等待—通知機(jī)制 什么是等待通知—機(jī)制?當(dāng)線程不滿足某個(gè)條件,則進(jìn)入等待狀態(tài);如果線程滿足要...
摘要:每個(gè)通過網(wǎng)絡(luò)到達(dá)服務(wù)器的連接都被包裝成一個(gè)任務(wù)并且傳遞給線程池。線程池的線程會(huì)并發(fā)的處理連接上的請(qǐng)求。用線程池控制線程數(shù)量,其他線程排隊(duì)等候。實(shí)現(xiàn)包,線程池頂級(jí)接口是但是嚴(yán)格意義講并不是一個(gè)線程。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求。 tutorial site1tutorial site2 一個(gè)問題: 每啟動(dòng)一個(gè)新線程都會(huì)有相應(yīng)的性能開銷(涉及到OS的交互:創(chuàng)建線程,銷毀線程...
摘要:虛擬機(jī)所處的區(qū)域,則表示它是屬于新生代收集器還是老年代收集器。虛擬機(jī)總共運(yùn)行了分鐘,其中垃圾收集花掉分鐘,那么吞吐量就是。收集器線程所占用的數(shù)量為。 本文主要從GC(垃圾回收)的角度試著對(duì)jvm中的內(nèi)存分配策略與相應(yīng)的垃圾收集器做一個(gè)介紹。 注:還是老規(guī)矩,本著能畫圖就不BB原則,盡量將各知識(shí)點(diǎn)通過思維導(dǎo)圖或者其他模型圖的方式進(jìn)行說明。文字僅記錄額外的思考與心得,以及其他特殊情況 內(nèi)存...
摘要:最后,總結(jié)一下,導(dǎo)致并發(fā)問題的三個(gè)源頭分別是原子性一個(gè)線程在執(zhí)行的過程當(dāng)中不被中斷。可見性一個(gè)線程修改了共享變量,另一個(gè)線程能夠馬上看到,就叫做可見性。 計(jì)算機(jī)的 CPU、內(nèi)存、I/O 設(shè)備的速度一直存在較大的差異,依次是 CPU > 內(nèi)存 > I/O 設(shè)備,為了權(quán)衡這三者的速度差異,主要提出了三種解決辦法: CPU 增加了緩存,均衡和內(nèi)存的速度差異 發(fā)明了進(jìn)程、線程,分時(shí)復(fù)用 CP...
摘要:除此之外,把并發(fā)安全字典封裝在一個(gè)結(jié)構(gòu)體類型中,往往是一個(gè)很好的選擇。請(qǐng)看下面的代碼如上所示,我編寫了一個(gè)名為的結(jié)構(gòu)體類型,它代表了鍵類型為值類型為的并發(fā)安全字典。在這個(gè)結(jié)構(gòu)體類型中,只有一個(gè)類型的字段。34 | 并發(fā)安全字典sync.Map (上)我們今天再來講一個(gè)并發(fā)安全的高級(jí)數(shù)據(jù)結(jié)構(gòu):sync.Map。眾所周知,Go 語言自帶的字典類型map并不是并發(fā)安全的。前導(dǎo)知識(shí):并發(fā)安全字典誕生...
閱讀 1572·2021-11-24 09:39
閱讀 1062·2021-11-22 15:11
閱讀 2202·2021-11-19 11:35
閱讀 1639·2021-09-13 10:37
閱讀 2472·2021-09-03 10:47
閱讀 2159·2021-08-30 09:47
閱讀 1642·2021-08-20 09:39
閱讀 2919·2019-08-30 14:13