2013-05-13 66 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

您可以在负责执行第一个终止的线程的构造函数中传递要终止的线程的引用。然后,您可以使用其他线程的引用来销毁该线程。