Java併發程式設計 死鎖及解決方法

2021-07-09 16:18:26 字數 1818 閱讀 1021

死鎖是多個程序\執行緒為了完成任務申請多個不可剝奪的資源並且以不正確的方式推進導致的一直互相等待對方釋放資源的狀態。下面以經典的哲學家就餐問題為例,描述死鎖產生的場景。

五個哲學家坐在乙個圓桌上,每個哲學家兩側都放著1根筷子,總共有5只筷子。哲學家需要分別或者左右手的兩隻筷子才能就餐,就餐完成後將筷子放回原處,其他哲學家可以獲取放回的筷子。有這樣一種狀態,每個哲學家都獲取了他右手的筷子,試圖獲取左手的筷子時都會失敗(被他左手邊的哲學家拿走了),然後所有哲學家都會一直等待他左手邊哲學家釋放筷子,這就導致了死鎖狀態。

public

class philosophereat

taken = true; //標記筷子被拿走

} finally

}// 放下筷子

public

void

put() throws interruptedexception finally }}

/** 哲學家就餐類

*/public

static

class philosopher implements runnable

* 250));

timeunit.milliseconds.sleep(10);

}//構造方法

public

philosopher(chop left, chop right, int id, int ponde***ctor)

@override

public

void

run()

} catch (interruptedexception e) {}}}

public

static

void

main(string args)

executorservice pool = executors.newcachedthreadpool();

for (int i = 0; i < size; i++)

try catch (ioexception e) {}

pool.shutdown();

}}

大部分情況下執行不會發生死鎖,就餐和思考時間越短越容易發生死鎖,這也是死鎖問題的可怕之處,不易復現。

死鎖的必要條件有如下四個:

乙個資源每次只能被乙個執行緒使用,如io等。

乙個程序因請求資源而阻塞時,對已獲得的資源保持不放。

程序已獲得的資源,在未使用完之前,不能強行剝奪。

若干程序之間形成一種頭尾相接的迴圈等待資源關係。

死鎖的必要條件必須全部滿足才會產生死鎖,所以要解決死鎖問題只需要任意破壞其中乙個條件就可以解決死鎖問題。

很多系統資源如io等必須是互斥的,破壞互斥條件的成本較大。

可以通過一次性獲取所有資源即對需要的資源進行原子申請可以解決死鎖問題,這種方式對系統開銷較大,不太理想。

可以通過定時釋放占有的資源解決死鎖問題,但是這也會帶來過多的資源占有釋放操作。

這是解決死鎖常用的方法,例如哲學家就餐問題中,最後乙個哲學家可以先拿左手的筷子,拿不到就會等待,他右手的筷子就可以供第乙個哲學家使用。

public

static

void

main(string args)

executorservice pool = executors.newcachedthreadpool();

for (int i = 0; i < size; i++) else

}try catch (ioexception e) {}

pool.shutdown();

}

java 死鎖現象及解決方法

摘自 所謂死鎖 是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。由於資源占用是互斥的,當某個程序提出申請資源後,使得有關程序在無外力協助下,永遠分配不到必需的...

死鎖及解決方法

死鎖的概念 quad 死鎖 指的是 quad 多個執行緒各自占有一些共享資源,並且互相等待其他執行緒占有的資源才能進行,而導致兩個或者多個執行緒都在等待對方釋放資源,都停止執行的情形。quad 因此,某乙個同步塊需要同時擁有 兩個以上物件的鎖 時,就可能會發生 死鎖 的問題。下面案例中,化妝執行緒 ...

死鎖現象及解決方法

死鎖現象 過多的同步可能造成相互不釋放資源 先定義兩個類,乙個口紅,乙個鏡子 class lipstick class mirror 化妝類 g0在鎖lipstick後又想鎖住mirror,g1在鎖住mirror後又想鎖住lipstick,當兩個同時都想擁有對方的鎖的時候,就會出現死鎖的現象。pub...