2016-09-27 54 views
0

我有3個線程,所有3做同樣的事情「[...]」(例如寫入列表中,我們同步):死鎖行爲

public void run(){ 
    long time= System.currentTimeMillis(); 
    while(System.currentTimeMillis - time < 10000){ 
    synchronized(object){ 
     [...] 
     object.notifyAll(); 
     object.wait(); 
    } 
    } 
    System.out.println(Thread.currentThread.getName() + " just finished"); 
} 

我發現好奇的是,當一個線程退出while循環時,會發生死鎖。我的問題不是它發生了,因爲它正是我正在測試的,但是當它發生時。在兩個線程完成後,不應該發生死鎖,因爲還有一個線程無法通過任何兩個線程完成通知?
當然有一個機會,兩個線程調用他們的「等待」在同一時間,所以我們得到的只是一個成品線後死鎖,因爲這兩個等待那些無法通過完成一個被喚醒,但我已經運行測試很多次,結果總是相同的:在完成一個線程後死鎖。

我錯過了什麼嗎?

+1

線程在等待什麼東西?見[這裏](http://howtodoinjava.com/core-java/multi-threading/how-to-work-with-wait-notify-and-notifyall-in-java/)關於如何實際等待的一些文檔爲了某件事。 –

+1

在這種情況下,沒有什麼具體的他們正在等待。我在另一個環境中注意到了這種行爲,並想爲它編寫一個簡單的測試。這個問題有點泛泛,但我不確定如何對它進行描述。 我以爲有三個線程,按照這個順序等待並通知,只有當一個線程都不在時,纔會導致死鎖,因爲幾乎所有線程都會通知其他線程。 我知道等待等待是不明智的。也許我只是花太多時間去思考通常不會發生的事情(即沒有條件的等待) – user6454491

+1

它只是不起作用。如果他們沒有什麼等待,他們就沒有辦法知道它是否已經發生。如果你等待已經發生的事情,你將永遠等待。所以這是一個絕對不可能工作的設計,除了運氣。要使用等待/通知你*必須*保持被等待的東西的狀態。你不能等待沒有特別的東西,它不會工作。 –

回答

1

wait功能會等待是否有什麼東西要等待還是不行。在致電wait之前,您必須檢查您想等待的事情是否已經發生 - 這就是您爲什麼在​​區塊中的原因,以便持有保護您正在等待的共享狀態的鎖定。

如果沒有某個共享狀態,您將永遠無法獲得wait/notifyAll,您正在等待達到某個特定狀態。您必須使用該鎖來保護該共享狀態,並且必須在調用wait之前檢查其狀態。否則,你將永遠有可能的比賽,包括你所看到的那種即使已經發生也要等待發生的事情,從而永遠等待。