2011-04-14 64 views
6

在用超時值調用加入並超時後,Java線程處於什麼狀態。因此,例如,您有以下代碼:加入超時值後,Java線程會發生什麼變化

Thread thread = new Thread(); 
thread.start(); 
thread.join(TIMEOUT); 

並且超時通過,並且線程還沒有返回什麼狀態?我需要注意什麼才能確保我不會泄漏線程。我最初的假設是,加入通話,做這樣的事情後:

if (thread.isAlive()) 
{ 
    thread.interrupt(); 
    thread = null; 
} 

要檢查是否線程仍在運行,並且如果是的話打斷,然後空出來,以確保它得到垃圾收集。

回答

5

Javadoc指出join(time)函數將最多等待線程死亡的毫秒數。實際上,如果超時通過,您的代碼將停止阻止並繼續。如果您在這種情況下擔心「泄漏線程」,您可能應該重新設計,以便您不必加入線程並可以觀察正在運行的線程的狀態。此外,在線程中調用中斷是不好的。

class MyThread extends Thread { 
    private boolean keepRunning = true; 
    private String currentStatus = "Not Running"; 
    public void run() { 
     currentStatus = "Executing" 
     while(keepRunning) 
     { 
      try { 
       someTask() 
       currentStatus = "Done"; 
      } catch (Exception e) { 
       currentStatus = "task failed"; 
       keepRunning = false; 
      } 
     } 
    } 

    public stopThread() { 
     keepRunning = false; 
    } 
} 

上面可能是一個更好的示例,可用於處理線程。您不需要將線程明確設置爲null,但是例如,如果您將線程存儲在ArrayList中,則將其從列表中移出並讓Java處理它。

+1

當然,如果你打算中斷與了Thread.interrupt()線程你應該在循環的入口點檢查Thread.interrupted()。 – 2011-04-14 02:05:05

+0

感謝您的示例代碼。我最終完成了這個工作,並定義了線程的狀態,如果超時,我取消線程。一旦我到達SnS階段,我會檢查內存/線程泄漏 – 2011-04-17 00:41:52

0

join將導致調用線程等待線程join被調用,死亡,即完成它的執行。因此,在您的示例中thread在暫停超時的時刻的狀態將不是TERMINATED(這就是發生超時的原因,而不是join「自然」返回(在這種情況下,thread將處於TERMINATED狀態) - 當然,在發生超時之後,thread幾乎可以立即轉換到TERMINATED狀態)。

調用線程的狀態將在時間到期後立即變爲RUNNABLE,並且直到那個時候,它的狀態纔會變爲TIMED_WAITING狀態。

0

假設您正在檢查中斷(Thread.interrupted()和InterruptedException),我看不出爲什麼這不起作用的原因。

的連接完成後成功我猜的線程可以在任何Thread.State但新

1

和超時的推移和線程還沒有回來是什麼狀態呢?

該點的線程狀態是不確定的。你可以說最好的是它不會是新的,並且可能不會被終止。 (但是,即使在後一種情況下,它可能已經進入終止狀態超時已經解僱,已經引起了超時異常調用的代碼之間)。

關於此代碼:

if (thread.isAlive()) { 
    thread.interrupt(); 
    thread = null; 
} 

這是保證如果線程仍處於活動狀態,則傳遞中斷。 (你嘗試中斷一個處於TERMINATED狀態的線程的機會很小,但是我對interrupt()的javadoc的閱讀是無害的。)

中斷的情況完全取決於線程。具體來說,不能保證線程會看到中斷,或者做預期的事情;即完成。 (A乖巧線程應定期檢查中斷標誌,而不應撳wait(...)sleep(...)的「中斷」的異常等)

nullthread分配會有影響最小。如果線程仍在運行,它/它的資源無論如何都不會被垃圾收集。如果線程被終止,這可能使Thread對象有資格進行垃圾回收。但這並沒有太大的區別。當一個線程進入TERMINATED狀態時,它的堆棧會自動釋放,它會從它的線程組中移除,並且它的鏈接到Runnable被禁止。一旦全部完成,Thread對象佔用的內存很少:從存儲泄漏的角度來看,沒有什麼需要關注的。

+0

我不認爲線程t0調用加入線程t0會根本改變j0的狀態。如果t1從連接中超時然後t1(或另一個線程)再次嘗試連接會怎麼樣? – seand 2011-04-14 02:24:55

+0

你說得對。但我不認爲我說或暗示......或OP說或暗示了這一點。 – 2011-04-14 03:21:08

相關問題