Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to interrupt a specific thread of an ExecutorService?

If I have an ExecutorService to which I feed Runnable tasks, can I select one and interrupt it?
I know I can cancel the Future returned (also mentioned Here: how-to-interrupt-executors-thread), but how can I raise an InterruptedException. Cancel doesn't seem to do it (event though it should by looking at the sources, maybe the OSX implementation differs). At least this snippet doesn't print 'it!' Maybe I'm misunderstaning something and it's not the custom runnable that gets the exception?

public class ITTest {
static class Sth {
    public void useless() throws InterruptedException {
            Thread.sleep(3000);
    }
}

static class Runner implements Runnable {
    Sth f;
    public Runner(Sth f) {
        super();
        this.f = f;
    }
    @Override
    public void run() {
        try {
            f.useless();
        } catch (InterruptedException e) {
            System.out.println("it!");
        }
    }
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
    ExecutorService es = Executors.newCachedThreadPool();
    Sth f = new Sth();
    Future<?> lo = es.submit(new Runner(f));
    lo.cancel(true); 
    es.shutdown();
}

}

like image 924
zeller Avatar asked Aug 21 '12 17:08

zeller


People also ask

How do I interrupt a thread in ExecutorService?

Then you can use below code to construct your ExecutorService instance: ExecutorService executorService = Executors. newFixedThreadPool(3, customThreadfactory); Then after 5 seconds, an interrupt signal will be sent to the threads in ExecutorService .

How do I interrupt a specific thread in Java?

interrupt() method: If any thread is in sleeping or waiting for a state then using the interrupt() method, we can interrupt the execution of that thread by showing InterruptedException. A thread that is in the sleeping or waiting state can be interrupted with the help of the interrupt() method of Thread class.

Can we interrupt a thread?

A thread can send an interrupt by invoking interrupt on the Thread object for the thread to be interrupted. This means interruption of a thread is caused by any other thread calling the interrupt() method. void interrupt() - Interrupts the thread.

How do you shut down an ExecutorService?

To properly shut down an ExecutorService, we have the shutdown() and shutdownNow() APIs. This method returns a list of tasks that are waiting to be processed. It is up to the developer to decide what to do with these tasks.


1 Answers

The right thing to do here is to cancel the Future. The issue is that this will not necessarily cause an InterruptedException.

If the job has yet to run then it will be removed from the runnable queue -- I think this is your problem here. If the job has already finished then it won't do anything (of course). If it is still running then it will interrupt the thread.

Interrupting a thread will only cause sleep(), wait(), and some other methods to throw InterruptedException. You will also need test to see if the thread has been interrupted with:

if (Thread.currentThread().isInterrupted()) {

Also, it is a good pattern to re-set the interrupt flag if you catch InterruptedException:

try {
   Thread.sleep(1000);
} catch (InterruptedException e) {
   // this is a good pattern otherwise the interrupt bit is cleared by the catch
   Thread.currentThread().interrupt();
   ...
}

In your code, I would try putting a sleep before you call lo.cancel(true). It may be that you are canceling the future before it gets a chance to execute.

like image 79
Gray Avatar answered Sep 21 '22 01:09

Gray