ExecutorService.shutdownNow()不会关闭线程

时间:2014-06-20 12:50:29

标签: java executorservice java.util.concurrent

我正在运行一个高度并发的Java程序。 虽然许多线程正在向执行程序服务提交任务,但在某个点上主线程调用ExecutorService.shutdownNow()

在此行动之后,我希望:

  1. 执行人服务不接受任何其他任务
  2. 执行程序服务的队列清晰
  3. 其余正在运行的工作程序被中断,也就是说,如果他们正确管理InterruptedException和/或明确检查Thread.currentThread().isInterrupted()
  4. ,他们会在某一时刻关闭

    因为我处于以下情况:

    1. 执行程序服务由于ExecutorService.shutdownNow()而“关闭”,但未关闭,即ExecutorService.awaitTermination(long, TimeUnit)永不返回true
    2. 我的执行程序服务管理的某些待处理线程在BlockingQueue.take()
    3. 上等待
    4. 如果我再次调用ExecutorService.shutdownNow(),则挂起的帖子会在InterruptedExceptionBlockingQueue.take()消失
    5. 我认为在调用BlockingQueue.take()之前,这些线程已经收到了中断,并且忽略了InterruptedException。

      我也想知道ExecutorService.shutdownNow()是否是线程安全的,即即使线程池正在接收许多提交,它也能正常工作。

      总而言之,我有两个问题:

      1. 有没有可以解释我情况的替代方案?
      2. ExecutorService.shutdownNow()是否可能是线程安全的?

1 个答案:

答案 0 :(得分:3)

  

有没有可以解释我情况的替代方案?

您的线程代码中必定存在重置中断标志或吞下由另一个方法调用引发的InterruptedException的内容。

如果在执行到达BlockingQueue.take()方法之前设置了中断标志,则该方法仍将抛出InterruptedException并中止。这在以下代码中进行了演示,该代码立即退出并打印"中断!":

final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);

Thread t = new Thread() {
    @Override
    public void run() {
        Thread.currentThread().interrupt();

        try {
            queue.take();
        } catch (InterruptedException e) {
            System.out.println("Interrupted!");
        }
    };
};
t.start();
  

ExecutorService.shutdownNow()是否可能是线程安全的?

例如,请参阅:Is ThreadPoolExecutor thread safe?。根据该答案,ExecutorService的所有标准实现都是线程安全的(即使Javadocs在该主题上不明确)。