Java並發中死鎖、活鎖和饑餓是什麼意思

解答

死鎖是指兩個或者兩個以上的進程(或線程)在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,他們將無法推進下去。

如果線程的智力不夠, 且都秉承著“謙讓”的原則,主動將資源釋放給他人使用,那麼就會導致資源不斷地在兩個線程間跳動,而沒有一個線程可以同時拿到所有資源正常執行。這種情況就是活鎖。

饑餓是指某一個或者多個線程因為種種原因無法獲得所需要的資源,導致一直無法執行。比如它的線程優先級可能太低,而高優先級的線程不斷搶占它需要的資源,導致低優先級線程無法工作。 

補充

死鎖

是指兩個或兩個以上的進程(或線程)在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生瞭死鎖,這些永遠在互相等待的進程稱為死鎖進程。

產生死鎖的原因

互相爭奪共享資源

產生死鎖的4大條件

1.互斥條件:共享資源被一個線程占用

2.請求與保持條件(占有且等待):一個進程因請求資源而被阻塞時,對已經獲得資源保持不釋放

3.不可剝奪條件(不可搶占):進程已獲得資源,在未使用完之前,不能進行剝奪

4.循環等待條件:多個線程 循環等待資源,而且是循環的互相等待

死鎖如何解決?

隻需要破壞上面 4 個條件中的一個就能破壞。

1.請求與保持條件:放大鎖范圍,去除對資源的搶占

2.不剝奪:換成可重入鎖ReentrantLock

3.循環等待:改成順序加鎖,避免循環等待

4.互斥是多線程的特性,所以這個條件無法避免

活鎖

是指線程1可以使用資源,但它很禮貌,讓其他線程先使用資源,線程2也可以使用資源,但它很紳士,也讓其他線程先使用資源。這樣你讓我,我讓你,最後兩個線程都無法使用資源。活鎖不會被阻塞,而是不停檢測一個永遠不可能為真的條件。除去進程本身持有的資源外,活鎖狀態的進程會持續耗費寶貴的CPU時間。

任務或者執行者沒有被阻塞,由於某些條件沒有滿足,導致一直重復嘗試、失敗、嘗試、失敗。在這期間線程狀態會不停的改變。

饑餓

是指如果線程T1占用瞭資源R,線程T2又請求封鎖R,於是T2等待。T3也請求資源R,當T1釋放瞭R上的封鎖後,系統首先批準瞭T3的請求,T2仍然等待。然後T4又請求封鎖R,當T3釋放瞭R上的封鎖之後,系統又批準瞭T4的請求……,T2可能永遠等待。

這也就是ReentrantLock顯示鎖裡提供的不公平鎖機制(當然瞭,ReentrantLock也提供瞭公平鎖的機制,由用戶根據具體的使用場景而決定到底使用哪種鎖策略),不公平鎖能夠提高吞吐量但不可避免的會造成某些線程的饑餓。

產生饑餓的原因

【即線程一直在等待卻無法執行的原因】

1.高優先級線程搶占資源線程

2.在等待一個本身也處於永久等待完成的對象

3.線程被永久阻塞在一個等待進入同步塊的狀態,因為其他線程總是能在他之前持續地對該同步塊進行訪問(比如阻塞在synchronized)

活鎖和死鎖的區別

死鎖會阻塞,一直等待對方釋放資源,一直處在阻塞狀態;活鎖會不停的改變線程狀態嘗試獲得資源。

活鎖有可能自行解開,死鎖則不行

 死鎖活鎖與饑餓的區別

進程會處於饑餓狀態是因為持續地有其它優先級更高的進程請求相同的資源。不像死鎖或者活鎖,饑餓能夠被解開。例如,當其它高優先級的進程都終止時並且沒有更高優先級的進程到達。

 到此這篇關於Java並發中死鎖、活鎖和饑餓是什麼意思的文章就介紹到這瞭,更多相關死鎖、活鎖和饑餓內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: