private final static Object MUTEX_READ = new Object();
private final static Object MUTEX_WRITE = new Object();
public void read(){
synchronized (MUTEX_READ) {
synchronized (MUTEX_WRITE) {
}
}
}
public void write(){
synchronized (MUTEX_WRITE) {
synchronized (MUTEX_READ) {
}
}
}
服務器開啓了某個端口,等待客戶端的訪問。客戶端發送請求後等待服務器的響應,服務器由於某種緣由錯過了客戶端的請求,讓在等待請求。此時,服務端可客戶端都在等待對方發送數據。
好比某個線程執行了for update語句後退出了事務,其餘線程訪問的時候就會陷入死鎖
獲取文件鎖的線程意外退出,其它線程沒法獲取該文件鎖會進入死鎖。
處理死鎖的方法服務器
經過設置某些限制條件,去破壞產生死鎖的四個必要條件中的一個或幾個條件,來防止死鎖的發生。【在死鎖產生的四個必要條件中,「互斥條件」是沒法破壞的,破壞「互斥條件」會形成結果的不可再現性】數據結構
容許對資源實行搶奪。
方法一:若是佔有某些資源的一個線程進行進一步資源請求被拒絕,則該線程必須釋放它最初佔有的資源【若是有須要,可再次請求這些資源和另外的資源】。
方法二:容許優先級高的線程搶佔優先級低的線程的資源。
在系統中不容許進程在已得到某種資源的狀況下,申請其餘資源。
方法一:採用「 一次性分配」方案,即:建立進程時,要求它申請所需的所有資源,系統或知足其全部要求,或什麼也不給它。
方法二:要求每一個進程提出新的資源申請前,釋放它所佔有的資源。
將系統中的全部資源進行編號,線程必須按照順序申請資源。
避免死鎖的處理方式
主要是針對那些不可能實現按序加鎖而且鎖超時也不可行的場景。每當一個線程請求或者得到了鎖,會在線程和鎖相關的數據結構中將其記下。
線程A等待線程B,線程B等待線程C,線程C等待線程D,線程D又在等待線程A。線程A爲了檢測死鎖,它須要遞進地檢測全部被B請求的鎖。從線程B所請求的鎖開始,線程A找到了線程C,而後又找到了線程D,發現線程D請求的鎖被線程A本身持有着。這是它就知道發生了死鎖。
檢測和解除死鎖
因爲操做系統有併發、共享以及隨機性等特色,經過預防和避免的手段達到排除死鎖的目的是很困難的。一種簡便的方法是系統爲進程分配資源時,不採起任何限制性措施,可是提供了檢測和解脫死鎖的手段:能發現死鎖並從死鎖狀態中恢復出來。所以,在實際的操做系統中每每採用死鎖的檢測和解除方法來排除死鎖。
死鎖檢測和解除是指系統設有專門的機制,當死鎖發生時,該機制可以檢測到死鎖發生的位置和緣由,並能經過外力破壞死鎖發生的必要條件,從而使得併發進程從死鎖狀態中恢復出來。
1) 資源剝奪法:掛起某些死鎖進程,並釋放它的資源,將這些資源分配給其餘的死鎖進程。【但應防止被掛起的進程長時間得不到資源,而處於資源匱乏的狀態】
2) 撤銷線程法:強制撤銷部分、甚至所有死鎖線程。【撤銷的原則能夠按進程優先級和撤銷進程代價的高低進行】
3) 進程回退法:讓一(多)個線程回退到足以迴避死鎖的地步【要求系統保持進程的歷史信息,設置還原點】