2013-01-11 71 views
2

我在stackoverflow上看到了一些帖子,並通讀了oracle發佈在銷燬線程上的教程。據我所知,一旦你start()一個線程,你不能使用stop()刪除該線程。不建議實際從調度程序中刪除該線程,而是建議無限期地創建線程sleep()。這個想法是對的嗎?銷燬Java中的線程

此外,這帶我到我的下一個問題,這就是爲什麼人們使用thread pools?.而不是「睡覺」一個線程,它是更多的資源,使用該線程來處理其他工作,而不是創建新的線程。請讓我知道,如果我對multi-thread管理的理解是正確的。 Java不允許以安全的方式完全刪除thread

回答

3

一旦線程啓動(或使其無限期休眠),強行停止線程通常被認爲是一個非常糟糕的主意,因爲線程無法清理其獲取的任何資源。例如,如果一個線程獲得一個鎖並被無限期地強行殺死或睡眠,那麼該鎖將不會被釋放,並可能發生死鎖。同樣,如果線程正在對數據結構進行更改並儘早殺死,那麼數據結構可能處於損壞狀態,從而在以後造成嚴重問題。

在Java中停止線程的最好方法是中斷線程並告訴它需要儘快關閉線程。這樣,線程可以嘗試停止它正在執行的操作,並在關閉之前釋放所有資源。換句話說,你要求要求這個線程關閉,而不是強行殺死它。

這與爲什麼線程池存在無關。線程池非常有用,因爲通常需要與創建或銷燬線程相關的一些開銷,這是由於跟蹤線程狀態和進度所需的內部JVM或OS級簿記。線程池可以讓線程回收並讓它們通過讓線程休眠直到任務準備好,然後喚醒並執行任務來執行不同的任務。這可能比產生新線程更快,自己執行任務,然後拆除線程。

希望這會有所幫助!

+0

這很有道理。我有一個登錄線程,當它完成我的另一個線程時,我想銷燬它。據我所知,它不應該使用任何鎖,所以我非常想把它告訴給.stop()。然而它是一個擺動線程,所以我可能不知道它在gui調度程序下的任何鎖定。我怎麼知道我簡單的gui線程可能鎖定什麼? –

1

作爲templatetypedef提到,你不應該強行停止一個線程,你應該發信號給一個線程停止。例如,每當你的線程被阻塞,應在while循環測試是阻止病情的不同,以及條件進行戒菸:

while (!condition && !stop) { 
    try { 
     someBlockingFunction(); // A lock, take on a BlockingQueue, etc. 
    } catch (InterruptedException e) { //ignored } 
} 

在退出while循環,請檢查如果我們已經通過另一個線程停止(stop = true),如果是的話從run()函數返回以允許線程自行清理。