2012-04-06 90 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()

​​