當執行緒呼叫物件的同步方法(synchronized method)時,執行緒取得該物件的鎖,直到方法執行結束後才會釋放。
下面範例演示了使用synchronized method時造成的deadlock。
Friend
類別,hi()
及hiBack()
皆宣告為synchronized method
Friend
public class Friend {
private String name;
public Friend(String name){
this.name = name;
}
public synchronized void hi(Friend friend){
String threadName = Thread.currentThread().getName();
System.out.println(threadName + ":" + this.name + ":" + friend.getName() + "甲霸沒?");
friend.hiBack(this);
}
public synchronized void hiBack(Friend friend){
System.out.println(this.name + ":" + "挖甲霸阿,恁勒?");
}
public String getName(){
return this.name;
}
}
執行時,宣告兩個執行緒thread-a
及thread-b
,分別呼叫Friend
物件的synchronized method。
public class Test {
public static void main(String[] args) {
Friend ming = new Friend("小明");
Friend hua = new Friend("大華");
Thread a = new Thread(() -> { // Runnable.run()
ming.hi(hua); // 取得ming的鎖
}, "thread-a");
Thread b = new Thread(() -> { // Runnable.run()
hua.hi(ming); // 取得hua的鎖
}, "thread-b");
a.start();
b.start();
}
}
當thread-a
呼叫ming.hi(hua)
時取得ming
的鎖,同樣地thread-b
呼叫hua.hi(ming)
時,取得hua
的鎖。當thread-a
要執行hi()
中的friend.hiBack(this)
時,因為friend
物件的實例為hua
,但此時hua
被thread-b
鎖定,因此必須等待thread-b
執行完hi()
方法並釋放鎖才會執行,然而同樣地thread-b
要執行hi()
中的friend.hiBack(this)
時也是必須等待thread-a
執行完hi()
方法並釋放鎖才會執行,因此形成了兩條執行緒互相等待的deaklock。
沒有留言:
張貼留言