2012-04-06 11 views
8

ThreadPoolを10個の固定スレッドで作成します。スレッドプール内のlongrunningスレッドを中断する必要があるときがあります。ほとんどの場合、スレッドがいくつかの操作でブロックされているため、タイムアウトが発生し、スレッドが中断します。私は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

によってqueue.take()の内側に洗浄されますか? – dash1e

+1

'get()'にタイムアウトを受け入れるオーバーロードがあることは知っていますよね? – erickson

+0

'StopWatch'とは何ですか? – erickson

答えて

7

スレッドの応答方法がわからないため、「所有していないスレッド」を中断しないでください。スレッドのスケジューリングを制御できないため、特定のスレッドが特定のタスクを中断した瞬間に特定のタスクを実行していることは実際には分かりません

実行者を与えたタスクを取り消したい場合サービスFuturecancel(true)を呼び出してください。あなたのタスクが割り込み要求を検出すると、Thread.currentThread().interrupt()を呼び出して中断された状態を保持する必要があります。

この場合、エグゼキュータはスレッド自体を中断し、割り込みが発生したときにそのスレッドがタスクを実行していたことを知っているので、中断をきれいに処理します。

+0

私はあなたが言及したとおりに正確に従っています、私は未来をキャンセルし、呼び出し先のスレッドで、私は中断の状態を保存します。 – Shamik

+1

@Shamikあなたのコードで 'cancel()'の呼び出しがありません。 – erickson

+0

この呼び出し可能なタスクをスレッドプールに送信し、future.cancel(true)を使用してタスクをキャンセルする、上記のコードの呼び出し側があります。 – Shamik

0

ステップバイステップデバッグから、私は中断されたスレッドがワーカーキューからgetTaskを続けると思います。 getTaskの前に中断されたステータスがすでにクリーンアップされています。あなたはLinkedBlockingQueueでFixedThreadPoolを使用している場合、例えば

、割り込みステータスは、使用しているスレッドプールの種類ReentrantLock.lockInterruptibly()

​​
関連する問題