2012-04-06 101 views
8

我创建了一个ThreadPool,其中包含10个固定线程。有时我需要中断线程池中的一个长时间运行的线程,主要是因为它们在某些操作中被阻塞,并且发生超时并且中断该线程。我找到InterruptedException并设置线程的状态为中断。在这种情况下,我的问题是ThreadPool是否创建了一个新的线程,并用新的线程替换了中断的线程? 下面是由线程执行的示例代码。问题是,当这个线程被中断时,线程池是否会将这个线程替换为一个新线程?java thead池执行程序如何处理中断线程

public ResponseMessage call(){ 
    Future<ResponseMessage> future = CacheManager.getInstance().asyncFetch(); 
    ResponseMessage response = null; 
    try { 
     response = future.get(); 
    } 
    catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
    } catch (ExecutionException ex) { 
     //create a blank response 
    } 

    return response; 
} 
+2

您使用的是什么样的线程池的清洗? – dash1e 2012-04-06 01:05:34

+1

你知道'get()'有一个接受超时的超载,对吗? – erickson 2012-04-06 01:11:41

+0

'StopWatch'做什么? – erickson 2012-04-06 01:14:11

回答

7

你不应该中断你不“拥有”的线程,因为你不知道他们是如何回应的。由于您无法控制线程调度,因此您确实不知道给定线程在您打断它的瞬间正在执行特定任务。

如果您要取消已给予执行程序的任务请拨打cancel(true)联系Future。当您的任务检测到中断请求时,它应通过调用Thread.currentThread().interrupt()来保持中断状态。

如果这样做,执行程序将干净地处理中断,因为它会中断线程本身,并且知道中断发生时线程正在执行任务。

+0

我完全按照您提到的,我取消了未来,并在被调用者线程中保留了中断的状态。 – Shamik 2012-04-06 01:10:22

+1

@Shamik我在代码中看不到任何对'cancel()'的调用。 – erickson 2012-04-06 01:15:50

+0

有一个上述代码的调用者,它将这个可调用任务提交给线程池并使用future.cancel取消任务(true) – Shamik 2012-04-06 01:18:28

0

从一步一步调试,我想中断的线程将继续从工作队列getTask。 getTask之前已经清除了中断状态。

例如,如果您使用的是FixedThreadPool用的LinkedBlockingQueue,中断状态的queue.take()内通过ReentrantLock.lockInterruptibly()

​​