4/10/2009

Java中的Deadlock情況!!

要知道deadlock的前提:
Thread A占用Resource B
Thread B占用Resource A

發生情況:
Thread A將Resource B鎖定(lock)住
;同時,
Thread B將Resource A鎖定(lock)住
Thread B要取用Resource B,結果Thead A仍未處理完,要等待!
Thread A要取用Resource A,結果Thread B仍未處理完,要等待!
最終,雙方同時等待造成Deadlock!

模擬Deadlock:
1.雙方同時sleep以致不會把lock object交還..
2.Thread A的sleep時間比Thread B長
(這樣做Thread B,會以為Thread A還在處理..!因為lock object沒交還..)
3.使用synchronized關鍵字來創造critical section..

代碼如下:
public class Main{
public static void main(string args[]){
Thread threadA=new Thread(new ThreadA());
Thread threadB=new Thread(new ThreadB());

threadA.start();
threadB.start();

}//end main
}//end Main
class ThreadA implements Runnable{
ResourceA resA=ResourceA.getInstance();
ResourceB resB=ResourceB.getInstance();

public void run(){
synchronized(resB){
System.out.println("ResourceB for ThreadA is starting!");
Thread.sleep(150);
synchronized(resA){
System.out.println("ResourceA for ThreadA is starting!");
}//end synchronized

}//end synchronized

}//end run

}//end ThreadA

class ThreadB implements Runnable{
ResourceA resA=ResourceA.getInstance();
ResourceB resB=ResourceB.getInstance();


public void run(){
synchronized(resA){
System.out.println("ResourceA for ThreadA is starting!");

Thread.sleep(50);
synchronized(resB){
System.out.println("ResourceB for ThreadA is starting!");
}//end synchronized


}//end synchronized


}//end run

}//end ThreadB
//------------------------------------------------------------------
//class Resource使用Singlaton Pattern來創造獨一無二的Resource

class ResourceA{
public volatile static ResourceA uniqueInstance;//控制統一鎖
private ResourceA(){

}//end constructor

public static ResourceA getInstance(){
if(uniqueInstance==null){
synchronized(your_class_for_ResourceA_name.class){
if(uniqueInstance==null)
uniqueInstance=new ResourceA();
}//end synchronized
}//end if
return uniqueInstance;
}//end getInstance


}//end ResourceA

class ResourceB{
public volatile static ResourceB uniqueInstance;//控制統一鎖
private ResourceB(){

}//end constructor

public static ResourceB getInstance(){
if(uniqueInstance==null){
synchronized(your_class_for_ResourceB_name.class){
if(uniqueInstance==null)
uniqueInstance=new ResourceB();
}//end synchronized
}//end if
return uniqueInstance;
}//end getInstance

}//end ResourceB
//------------------------------------------------------------------