2013-05-13 97 views
1

在我的應用程序中,每個請求都有自己的線程。我使用JMX/JConsole來監視它們,測量已用時間。如果請求需要太多時間,我想通過中斷底層線程來停止它。 在我從JConsole調用的方法中,遍歷線程列表並在正確的實例上調用interrupt()。
然而,簡單地調用線程實例上的interrupt()方法只會設置一個標誌,所以我也需要拋出一個InterruptedException。 但是這個InterruptedException將應用於currentThread,而不是我實際上想要停止的線程。任何提示如何關閉標記的線程?如何關閉另一個線程?

while (iterator.hasNext()) { 
        RequestHolder rh = iterator.next(); 
        if (rh.getThread().getId() == threadId) { 
         rh.getThread().interrupt(); 
         if(rh.getThread().isInterrupted()){ 

          throw new InterruptedException(); 
         } 
        } 
       } 

回答

2

但這InterruptedException的將適用於currentThread而不是線程其實我是想停下來。

您可以使用isInterrupted檢查任何線程的中斷狀態。但是,如果您不知道如何以及何時中斷消耗,則不推薦將其作爲黑盒方法。

任何提示如何關閉標記的線程?

您不能從另一個線程乾淨地關閉一個線程。

但它很簡單。在正在運行的線程中,定期檢查Interruption,例如在循環捕獲InterruptedException中進行阻塞功能。當你看到線程中斷時,使其自行終止。從某種意義上說,線程實現了他們自己的終止策略。

+0

只是要注意 - 一些阻塞的第三方函數可以包裝InterputException在其他一些,如IOException左右(軸這樣做)。所以總是檢查是否中斷。 – JIV 2013-05-13 14:22:21

1

拋出InterruptedException沒有任何好處。你的if (rh.getThread().isInterrupted())塊可以被刪除。

每個線程都必須監視自己的中斷狀態,並且必須在發現它已被中斷時正常退出。

通常的代碼看起來是這樣的:

try { 
    InputStream in = socket.getInputStream(); 
    while (in.read(buffer) >= 0) { 
     if (Thread.interrupted()) { 
      logger.log(Level.FINE, "Interrupted; exiting"); 
      break; 
     } 

     // Process request buffer here 
    } 
} catch (InterruptedIOException e) { 
    logger.log(Level.FINE, "Interrupted; exiting", e); 
} 

如果使用頻道,你要趕上ClosedByInterruptException爲好。

0

您可以在負責執行第一個終止的線程的構造函數中傳遞要終止的線程的引用。然後,您可以使用其他線程的引用來銷燬該線程。