Java死鎖舉例

死鎖:

    在多線程競爭使用共享資源的情況下,就有可能出現死鎖的情況。比如,當一個線程等待另一個線程所持有的鎖時,那個線程又可能在等待第一個線程所持有的鎖。此時,這兩個線程會陷入無休止的相互等待狀態,這種情況就稱爲死鎖。

產生死鎖的四個必要條件:

1、互斥條件。進程對所分配的資源進行排它性控制,即在一段時間內某資源僅爲一進程所佔有。

2、請求和保持條件。當進程因請求資源而阻塞時,對已獲得的資源保持不放。

3、不剝奪條件。進程已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放。

4、環路等待條件。在發生死鎖時,必然存在一個進程-資源的環形鏈,即進程集合{P1,P2,。。。,Pn}中的P1等待一個P2佔用的資源,P2正在等待一個P3佔用的資源,。。。,Pn正在等待已被P1所佔用的資源。


比較簡單的解決死鎖的方法是通過設置某些限制條件,去破壞產生死鎖的四個必要條件中的一個或者幾個,來預防發生死鎖。預防死鎖是一種較易實現的方法,已被廣泛使用。但是由於所施加的限制條件往往太嚴格,可能會導致系統資源利用率和系統吞吐量降低。

下面是產生死鎖的一個示例:

package com.hh.deadLock;

public class DeadLockDemo {

	public static void main(String[] args) {
		final Object resource1 = "資源1";
		final Object resource2 = "資源2";
		Thread t1 = new Thread(){
			public void run() {
				synchronized(resource1){
					System.out.println("線程1:獲取資源1使用權");
					try {
						Thread.sleep(500);
					} catch (Exception e) {	}
					synchronized(resource2){
						System.out.println("線程1:等待資源2");
					}
				}
			}
		};
		Thread t2 = new Thread(){
			public void run() {
				synchronized(resource2){
					System.out.println("線程2:獲取資源2使用權");
					try {
						Thread.sleep(500);
					} catch (Exception e) {	}
					synchronized(resource1){
						System.out.println("線程2:等待資源1");
					}
				}
			}
		};
		
		t1.start();
		t2.start();
	}
}

程序會先打印出

線程1:獲取資源1使用權
線程2:獲取資源2使用權
或者是

線程2:獲取資源2使用權
線程1:獲取資源1使用權
然後程序就不再往下執行

線程t1獲取“資源1”使用權後等待“資源2”,而線程t2獲取“資源2”使用權後等待“資源1”,這樣,線程t1和線程t2就引起了死鎖。

如果將程序中的Thread.sleep(500);這行代碼註釋,則程序可能引起死鎖,也可能不引起。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章