【问题标题】:Is it possible to interrupt a specific thread of an ExecutorService?是否可以中断 ExecutorService 的特定线程?
【发布时间】:2012-08-21 17:48:09
【问题描述】:

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

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

}

【问题讨论】:

  • 你不应该知道ExecutorService 是如何安排它的线程的。你怎么能取消其中的一个?
  • 你明白了,但如果我有某种生产者消费者模式,我应该能够通过中断来停止非响应线程,但我不能这样。或者我应该设计它以便 Future.cancel 有资格取消?
  • 是的,@zeller,将其设计为与Future.cancel() 一起使用。这就是它的用途。

标签: java multithreading executorservice


【解决方案1】:

这里正确的做法是取消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) 之前放置一个睡眠。可能是您正在取消未来它有机会执行之前。

【讨论】:

  • ... 并且 InterruptedExceptions 必须被调用 sleep() 或 wait() 的任何东西捕获,这意味着它可能无法进入您的代码。通常,调用 Thread.interrupt() 不会自动停止线程的执行。只有在执行代码正在检查中断标志时它才有效。因此,通常很难改造现有代码以响应中断。
  • 考虑到 Oracle JDK 7 实现在内部使用中断,我可能建议不要中断由 ThreadPoolExecutor 管理的工作线程。
猜你喜欢
  • 2011-01-26
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 2010-12-14
  • 2012-08-08
  • 2011-09-28
  • 1970-01-01
相关资源
最近更新 更多