【问题标题】:ScheduledExecutorService worker threads retain interrupted status after FutureTask.cancel(true)ScheduledExecutorService 工作线程在 FutureTask.cancel(true) 之后保持中断状态
【发布时间】:2010-11-10 20:40:23
【问题描述】:

我有一个任务,我计划通过ScheduledThreadPoolExecutor.scheduleAtFixedRate(task, rate, ...) 定期运行。用户可以手动取消此任务,这会调用ScheduledFuture.cancel(true)。出于某种原因,可能取决于他们何时取消此任务,工作线程(执行程序用来运行我的任务)在我的任务的 run() 方法退出后似乎保持中断状态。

虽然工作线程(从池中获取并重用)会在使用现有钩子(通过ThreadPoolExecutor.beforeExecute()ThreadPoolExecutor.afterExecute())开始新任务之前清除其中断状态。但在默认实现中并没有这样做。

我有两个问题:

  • 怎么让工作线程处于设置了中断状态的状态?
  • 为什么默认实现在开始新任务之前不清除中断状态?

【问题讨论】:

  • 尽管使用了各种时间,但我看不到这种行为。你能描述一下如何可靠地重现这个吗?
  • 我希望我自己能更好地理解它,任务本身使用了使用 ReentrantLock.lockInterruptibly() 的 ArrayBlockingQueue.take()。我相信这与它有关,我仍在尝试了解它是如何发生的(问题的第二部分)
  • 您使用的是哪个 JDK(版本、供应商、操作系统等)?
  • 我想我找到了:任务启动了一个单独的预取线程,该线程将工作单元放入队列中,关闭竞争条件将终止工作单元留在队列中,强制提前关闭重新触发竞争条件(并中断线程)。

标签: java multithreading concurrency interrupt executorservice


【解决方案1】:
* How is it that the worker thread is left in a state where the interrupt status is set?
* Why does the default implementation not clear the interrupt status before starting a new task?

答案是:

  • 它不会处于中断状态。
  • 实现了,但您没有找到正确的位置

来自 Oracle 库代码:

        /*
         * Ensure that unless pool is stopping, this thread
         * does not have its interrupt set. This requires a
         * double-check of state in case the interrupt was
         * cleared concurrently with a shutdownNow -- if so,
         * the interrupt is re-enabled.
         */
        if (runState < STOP &&
            Thread.interrupted() &&
            runState >= STOP)
            thread.interrupt();

如您所见,只要执行器没有关闭,中断状态就会从工作线程中清除。

【讨论】:

  • 没错!我第一次看到那段代码并将其误读为仅在池关闭时应用。我仍然不知道我是如何得到中断异常的;也许我在没有意识到的情况下同时取消和安排任务。
  • 如果用户在任务执行过程中取消,如何处理下一次阻塞调用时抛出的InterruptedException?
  • 我只是抓住它,记录它并返回(它是一个可重新启动的批处理)
【解决方案2】:

用户如何中断线程?如果他们使用的是 UI 组件,则您的问题可能是由于事件调度线程的同步问题造成的。

【讨论】:

  • 它不是一个摇摆应用程序。正如问题中所说:任务(FutureTask)被某个任意线程通过ScheduledFuture.cancel(true)取消。
猜你喜欢
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
  • 2011-04-04
  • 1970-01-01
  • 2018-10-22
  • 2021-05-26
  • 2020-11-30
  • 1970-01-01
相关资源
最近更新 更多