java死鎖的例子



死鎖是這樣一種情形:多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放。由於線程被無限期地阻塞,因此程序不可能正常終止。  

導致死鎖的根源在於不適當地運用“synchronized”關鍵詞來管理線程對特定對象的訪問。“synchronized”關鍵詞的作用是,確保在某個時刻只有一個線程被允許執行特定的代碼塊,因此,被允許執行的線程首先必須擁有對變量或對象的排他性的訪問權。當線程訪問對象時,線程會給對象加鎖,而這個鎖導致其它也想訪問同一對象的線程被阻塞,直至第一個線程釋放它加在對象上的鎖。  

由於這個原因,在使用“synchronized”關鍵詞時,很容易出現兩個線程互相等待對方做出某個動作的情形。代碼一是一個導致死鎖的簡單例子。 


package com.thread;

public class TestThread13 {
	
	public static void main(String[] args) {
		
		DeadLock t1 = new DeadLock();
		DeadLock t2 = new DeadLock();
		t1.flag = 1;
		t2.flag = 0;
		new Thread(t1).start();
		new Thread(t2).start();

	}

}

class DeadLock implements Runnable{

	public int flag = 1 ;
	static Object o1 = new Object(), o2 = new Object();
	public void run() {
		
		System.out.println("flag :"+flag);
		if (flag == 1) {
			synchronized (o1) {
				System.out.println(Thread.currentThread().getName()+" o1 locked");
				try{Thread.sleep(500);}catch(Exception e){e.printStackTrace();}				
				synchronized (o2) {
					System.out.println(Thread.currentThread().getName()+" o2 locked");
					System.out.println("1");
				}
			}
			
		}
		if (flag == 0) {
			synchronized (o2) {
				System.out.println(Thread.currentThread().getName()+" o2 locked");
				try{Thread.sleep(500);}catch(Exception e){e.printStackTrace();}
				synchronized (o1) {
					System.out.println(Thread.currentThread().getName()+" o1 locked");
					System.out.println("0");
				}
				
			}
			
		}
		
	}
	
}

運行結果:


分析:t1線程啓動了,但並沒有打印“1”;t2線程啓動了,但並沒有打印"0".因爲2個線程啓動後都阻塞了。

說明: t1線程啓動後,佔領監視器o1後,休眠500毫秒,這時t2線程佔領了監視器o2,從此以後程序就堵塞了。正如截圖結果。

原因是,t1線程佔有監視器o1,等待t2線程釋放監視器o2;同時,t2線程佔有監視器o2,等待t1線程釋放監視器o1, t1和t2這兩個線程都在等對方先釋放監視器,結果誰都不先釋放,所以2個線程會一直堵塞。t1線程不能繼續執行打印"1", t2線程不能繼續執行打印“0”。

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