10
votes

I create a ThreadPool with 10 fixed threads in it. At times I need to interrupt a longrunning thread in the thread pool, mostly because they are blocking in some operation and a timeout happens and I interrupt the thread. I catch the InterruptedException and set the Thread's status to interrupt as well. In that case, my question is, does ThreadPool create a new Thread and replace the interrupted thread with a new One ? Below is the example code which gets executed by the Thread. Question is, when this thread get interrupted, does thread pool replace this thread with a new one ?

 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
what kind of threadpool are you using? - dash1e
You know that get() has an overload that accepts a time-out, right? - erickson
Please ignore the stopwatch, and yes, I know about get with time-out method. - Shamik

2 Answers

7
votes

You should not interrupt threads that you do not "own," because you don't know how they respond. Since you don't have control over the thread scheduling, you really don't know that a given thread is executing a particular task at the instant you interrupt it

If you want to cancel a task you've given an executor service, call cancel(true) on its associated Future. When your task detects an interrupt request, it should preserve the interrupted status by calling Thread.currentThread().interrupt().

If you do this, the executor will handle the interruption cleanly because it interrupted the thread itself, and knows that the thread was executing a task when the interrupt occurred.

0
votes

From the step by step debugging, I suppose the interrupted thread will continue to getTask from the worker queue. The interrupted status already cleaned up before getTask.

For example, if you are using FixedThreadPool with LinkedBlockingQueue, the interrupted status is cleaned inside of queue.take() by ReentrantLock.lockInterruptibly()

public final void acquireInterruptibly(int arg) throws InterruptedException {
    if (**Thread.interrupted()**)
        throw new InterruptedException();
    if (!tryAcquire(arg))
         doAcquireInterruptibly(arg);
}