2011-04-01 94 views
0

如果我繪製一個圖形來象徵所有可能的調用阻塞函數(java同步方法)並且我沒有在這個圖中有任何循環,我可以肯定死鎖是不可能的。培訓網不能像那樣工作嗎?沒有循環的死鎖

我不是在尋找像這樣的答案:使用一些怪物框架blahblah。

我想用同步方法處理我的多線程。

EDIT1:尖箭頭表示如果一個類調用另一個類 EDIT2的任何同步方法:klick @here的例子中,示出了週期沒有​​鍵字

回答

0

號考慮:

private static final Semaphore foo = new Semaphore(1); 
private static final Semaphore bar = new Semaphore(1); 

private static void one() throws InterruptedException { 
    foo.acquire(); 
    bar.acquire(); 
    bar.release(); 
    foo.release(); 
} 

private static void two() throws InterruptedException { 
    bar.acquire(); 
    foo.acquire(); 
    foo.release(); 
    bar.release(); 
} 

爲可運行例如參見http://pastebin.com/QfK5ZByj。它對我來說很快就會陷入僵局。

+0

好吧,這很有趣。如果箭頭是線條(指向兩個方向),那麼它將是一個循環。單向箭頭不是一個循環。 – 2011-04-01 11:35:54

0

一些方法可能會阻塞。這適用於包java.util.concurrent中的許多方法。您還應該考慮方法內的​​塊。

如果僅考慮同步方法,則可以在方法調用中沒有循環的情況下產生死鎖,因爲同步方法將對象實例用作監視器。例如,如果您有兩個對象A和B,每個對象具有同步方法1()和2()。如果A.1()調用B.1()和B.2()調用A.2(),雖然方法中沒有循環,但如果一個線程同時調用B.2()而另一個調用A.1(),那麼有一個僵局風險。

+0

好吧我想我解釋錯了。如果一個班級另一個班級打電話,我正在談論繪製一個尖箭頭。所以箭頭在課堂級別而不是方法級別。但是如果使用同步類,我只考慮繪製箭頭。你懂我的意思嗎? :-) – 2011-04-01 10:00:58

2

不,這還不夠。假設你必須有線程:A和B.調用對象​​o1的方法m1,它調用對象o2的方法m1。線程B調用對象o2的方法m2,該方法調用對象o1的方法m2。假設所有的方法都是同步的。現在,A和B的併發執行會導致死鎖。雖然方法之間沒有循環調用關係。

是功課嗎?

即使您對關於類的編輯還不夠,因爲您可以通過非同步方法調用來關閉循環。

+0

有趣的是,如果您繪製的是對象而不是方法的圖形,則存在一個循環:o1 - > o2 - > o1。這是否適用於所有不涉及等待/通知的死鎖情況?儘管如此,這可能不是一種讓你在練習中非常有效的方法。 – 2011-04-01 10:30:31

+0

看看我編輯過的picutre,它顯示了tom描述的內容。我只在對象級別上討論連接。我的第一個描述是錯誤的... – 2011-04-01 11:28:20

+0

@Franz Kafka:看,我的答案的最後一句。 – jmg 2011-04-01 11:34:11