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();
}
}
Best Answer
The right thing to do here is to cancel the
Future
. The issue is that this will not necessarily cause anInterruptedException
.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 throwInterruptedException
. You will also need test to see if the thread has been interrupted with:Also, it is a good pattern to re-set the interrupt flag if you catch
InterruptedException
: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.