Java ScheduledExecutorService工作线程在FutureTask之后保持中断状态。取消(true)
我有一个任务,我计划通过它定期运行。用户可以手动取消此任务,这将调用。出于某种原因,可能取决于他们取消此任务的时间,在我的任务的run()方法退出后,工作线程(执行者用来运行我的任务)似乎仍处于中断状态 我认为工作线程(从池中提取并重新使用)在使用现有挂钩(通过或)启动新任务之前会清除其中断状态。但它在默认实现中不这样做 我有两个问题:Java ScheduledExecutorService工作线程在FutureTask之后保持中断状态。取消(true),java,multithreading,concurrency,interrupt,executorservice,Java,Multithreading,Concurrency,Interrupt,Executorservice,我有一个任务,我计划通过它定期运行。用户可以手动取消此任务,这将调用。出于某种原因,可能取决于他们取消此任务的时间,在我的任务的run()方法退出后,工作线程(执行者用来运行我的任务)似乎仍处于中断状态 我认为工作线程(从池中提取并重新使用)在使用现有挂钩(通过或)启动新任务之前会清除其中断状态。但它在默认实现中不这样做 我有两个问题: 工作线程是如何处于设置了中断状态的状态的 为什么默认实现在开始新任务之前不清除中断状态 用户是如何中断线程的?如果他们正在使用UI组件,您的问题可能是由于事件
- 工作线程是如何处于设置了中断状态的状态的
- 为什么默认实现在开始新任务之前不清除中断状态
- 它不会处于中断状态
- 实现确实如此,但您没有找到正确的位置
- 用户是如何中断线程的?如果他们正在使用UI组件,您的问题可能是由于事件调度线程的同步问题造成的
答案是:
/*
* 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();
/*
*确保除非池停止,否则此线程
*没有设置其中断。这需要一个
*在中断被中断的情况下,对状态进行双重检查
*与立即关闭同时清除--如果是,
*中断被重新启用。
*/
如果(运行状态<停止&&
Thread.interrupted()&&
运行状态>=停止)
thread.interrupt();
如您所见,只要执行器没有关闭,工作线程的中断状态就会被清除。它不是swing应用程序。正如问题中所说:任务(未来任务)是由某个任意线程通过
ScheduledFuture.cancel(true)
取消的。尽管使用了各种计时,我还是看不到这种行为。你能描述一下如何可靠地重现它吗?我希望我自己能更好地理解它,任务本身使用ArrayBlockingQueue.take(),它使用ReentrantLock.lockInterruptibly()。我相信这与此有关,我仍在试图弄清楚它是如何发生的(问题的第二部分)您使用的是哪个JDK(版本、供应商、操作系统等)?我想我找到了:任务启动一个单独的预取线程,将工作单元放入队列,关闭争用条件将终止程序工作单元留在队列中,强制提前关闭,从而重新触发争用条件(并中断线程)。这是真的!我第一次看到这段代码,并将其误读为仅在池关闭时才应用。我仍然不知道如何得到中断的异常;也许我正在同时取消和安排任务而没有意识到它。如果用户在任务执行时取消,你如何处理在下一个阻塞调用时抛出的InterruptedException?我只是捕获它,记录它并返回(这是一个可重启的批处理过程)
/*
* 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();