6

如果我有一个ExecutorService可以提供 Runnable 任务的任务,我可以选择一个并中断它吗?
我知道我可以取消返回的 Future (这里也提到:how-to-interrupt-executors-thread),但我怎样才能提出InterruptedException. Cancel 似乎没有这样做(事件虽然应该通过查看源代码,但 OSX 实现可能不同)。至少这个片段不会打印“它!” 也许我误解了一些东西,而不是自定义可运行对象获得异常?

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();
}

}

4

1 回答 1

11

正确的做法是取消Future. 问题是这不一定会导致InterruptedException.

如果作业尚未运行,那么它将从可运行队列中删除——我认为这是你的问题。如果工作已经完成,那么它不会做任何事情(当然)。如果它仍在运行,那么它将中断线程

中断一个线程只会导致sleep(),wait()和其他一些方法抛出InterruptedException。您还需要测试以查看线程是否已被中断:

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

此外,如果你抓住了,重新设置中断标志是一个很好的模式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();
   ...
}

在您的代码中,我会尝试您调用lo.cancel(true). 可能是您在未来有机会执行之前取消了它。

于 2012-08-21T17:50:51.483 回答