死锁的原因详解
當同步使用過多時會出現死鎖的情況。以下代碼實現死鎖:
//死鎖的實現
class A
{ public void get(){ System.out.println("A說:我開始啟動了,B,給我你的資源"); } public void say(){ System.out.println("A獲得資源"); }
}
class B
{ public void get(){ System.out.println("B說:我開始啟動了,A,給我你的資源"); } public void say(){ System.out.println("B獲得資源"); }
}
class MyThread implements Runnable
{ public static A a = new A(); public static B b = new B(); public boolean flag = false; public void run(){ if(flag){ synchronized(a){ a.get(); try{ Thread.sleep(500); }catch(InterruptedException e){} synchronized(b){ //此同步代碼塊在另一同步代碼塊里 a.say(); } } }else{ synchronized(b){ b.get(); try{ Thread.sleep(500); }catch(InterruptedException e){} synchronized(a){ //此同步代碼塊在另一同步代碼塊里 b.say(); } } } }
}
public class Demo24
{ public static void main(String args[]){ MyThread mt1 = new MyThread(); MyThread mt2 = new MyThread(); mt1.flag=true; mt2.flag=false; Thread th1 = new Thread(mt1); Thread th2 = new Thread(mt2); th1.start(); th2.start(); }
}
以上代碼由于synchronized的同步造成了死鎖,死鎖是兩個或多個線程同時等待對方的完成,而程序無法繼續執行。在解釋代碼前,首先要明白synchronized到底是怎么一回事。synchronized定義同步,那么同步的什么,什么和什么同步了?
首先,我們得知道,什么是鎖。在java中,每一個對象都有一個內部鎖,如果以方法或代碼塊用synchronized進行聲明,那么對象的鎖將保護整個方法或代碼塊,要調用這個方法或者執行這個代碼塊,必須獲得這個對象的鎖。而且,任何時候都只能有一個線程對象執行被保護的代碼
在以上代碼中,在線程th1啟動后,他就獲得了a的鎖,同時當其休眠完畢,求會申請獲得b的鎖,而此時,他的a鎖沒有放棄。
在線程th2啟動后,他就獲得了b的鎖,同時當其休眠完畢,求會申請獲得a的鎖,而此時,他的b鎖沒有放棄。
兩方都握有自己的鎖不放棄,而同時申請另一方的鎖,所以,此時就造成了死鎖。
同步,同步的就是線程和對象,將線程和對象進行綁定,獲取對象的鎖。
注意:通過以上代碼可以發現,死鎖的必要條件是不放棄已有的鎖,而同時申請新鎖。所以,要想實現死鎖,就會有synchronized的嵌套。
這樣才能同時操作兩個以上的鎖,從而造成死鎖。
轉自:http://blog.csdn.net/xiaoya629/article/details/5519538總結
- 上一篇: 线程中断问题详解
- 下一篇: java 多线程经典例子——生产者与消费