2016-02-25 81 views
4

我正在使用源代碼分析器,指出notifyAll()不應該在一個線程實例中調用。我試圖向管理層說明這一點,但我無法提出解釋。有人能幫我嗎??爲什麼在線程實例中不能使用notifyAll()?

順便說一下,這是繼承代碼,所以我不負責設計決策!

+2

什麼源代碼分析器指出了這一點? – Ferrybig

+0

該工具是SONAR。 – user1660256

+0

你的意思是「在一個線程實例內」到底是什麼意思?代碼調用'notifyAll'的方式有什麼不對嗎? –

回答

7

這聽起來像你所看到的SONAR消息this one

方法 「等(...)」, 「通知()」 和 「notifyAll的()」 不應該叫上螺紋實例 魷魚:S2236

聲納對此有着詳細的解釋:

在一個線程實例,方法等(...),通知()和notifyAll的()是availabl僅因爲Java中的所有類都擴展了Object,因此會自動繼承這些方法。但是有兩個非常好的理由不能在Thread實例中調用這些方法:

這樣做確實令人困惑。當調用線程時,真正需要什麼,例如,wait(...)方法?線程的執行是否被暫停,或者等待對象監視器的獲取?

在內部,JVM依靠這些方法來更改線程的狀態(BLOCKED,WAITING,...),因此調用它們將會破壞JVM的行爲。

同樣,advice given in the Java API是:

建議應用程序不使用等待,通知,或notifyAll的上螺紋實例。

內部線程管理通過鎖定線程對象來完成。如果您自己的應用程序代碼鎖定在線程上,您可能會遇到意外或令人困惑的行爲例如,當線程終止時,它會向等待它的每個線程發送一個通知。

在試圖評估問題的可能性時,我會尋找線程可能接收到錯誤通知或由於被用作應用程序代碼的鎖而錯誤地通知通知的情況,以及作爲內部JVM的鎖碼。 (這看起來可能很乏味。)根據代碼,我還會尋找由於鎖定線程而可能出現的一致性問題,而不是鎖定線程訪問的數據結構,並評估鎖定方案是否有意義。如果代碼是子類化線程,我想檢查線程是否合併以及如何。

大部分這個消息會讓我想,如果這段代碼是做這一件壞事,那麼它還有什麼可能做錯了? SONAR消息只是暗示它在代碼中發現了一種難聞的氣味,因此您可以調查並查看問題的嚴重性。

+0

我想我的問題是,如果這段代碼留在原地,行爲會是什麼?我們能說的最多的是意想不到的?我想更具體一些。 – user1660256

+0

@ user1660256您必須仔細查看特定代碼並分析其與線程狀態轉換的交互。警告的原因是,沒有人想要這樣做,或者冒他們做錯的風險。因此警告。 –

+0

@ user1660256:David是對的。沒有一個非常具體的例子很難說。線程問題可能會間歇性地出現,或者在某些平臺上而不是在其他平臺上顯示。我會分析代碼並檢查通知可能會丟失或可能被誤導的情況。 –

0

你不應該分類線程。這樣做會打開一系列相當熟悉的問題。使用wait/notifyAll並不是一個很好的選擇,因爲併發庫是在十多年前添加的,但在Thread上它特別糟糕,因爲Thread類也使用wait/notify來達到自己的目的。

相關問題