【问题标题】:When using an ExecutorService, is it possible for a Thread to become uninterruptible when in the WAITING state使用 ExecutorService 时,线程是否可以在 WAITING 状态下变得不可中断
【发布时间】:2017-12-12 01:55:54
【问题描述】:

我遇到了一个问题,似乎线程在 WAITING 状态下变得不可中断。任务线程本身(您将在下面的线程堆栈中看到)正在等待调用 FuturePromise.get()(一个 Jetty 类)。

任务线程正在 ExecutorService 的上下文中执行。下面是 ExecutorService 调用的样子(简化)。

ExecutorService es = Executors.newFixedThreadPool(8, new CustomizableThreadFactory("Test-Thread-"));
es.submit(taskToRun);
es.shutdown();
es.awaitTermination(10, TimeUnit.SECONDS);
es.shutdownNow();
String result = taskToRun.get();

我看到的是主线程卡在taskToRun.get() 等待任务完成/被中断,而运行任务的线程处于这种状态:

"Test-Thread-1" 
#135245 prio=5 os_prio=0 tid=0x00007f972c0c2000 nid=0x6838 waiting on condition [0x00007f96ca165000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x00000005d00d1118> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
at org.eclipse.jetty.util.FuturePromise.get(FuturePromise.java:118)
... + app code

我期望发生的是 Test-Thread-1 将被中断,这将引发 InterruptedException,而 taskToRun.get() 调用也会引发 InterruptedException。

很遗憾,我无法通过单元测试重现此问题,但我会在获得更多信息后更新。

【问题讨论】:

  • 你期待ExecutorService.shutdownNow()会导致线程中断吗? (即使 javadoc 说它可能不会)
  • 中断发生时,无法证明作业在get()方法内。你的工作中可能有任何你没有表现出来的东西,包括捕捉InterruptedException 或在进入get() 之前轮询/清除中断状态……
  • 我是迈克的同事。我们期望awaitTermination 使执行器服务超时并中断其线程。 shutdownNow 基本上只是一个清理步骤,假设 executorService 已经完成工作或超时。
  • > 可以是你工作中的任何东西,你没有显示,包括在进入 get() 之前捕获 InterruptedException 或轮询/清除中断状态 对,所以我们没有看到任何东西在我们工作的任何其他地方捕获了一个 InterruptedException。我想我们很困惑executorService 是如何处理这些超时的,以及如果我们在关闭之后很久才访问Future.get 时会抛出 InterruptedException。理论上,InterruptedException 是否会在内部存储,然后在最终调用 Future.get 时重新抛出?
  • @Bradley,awaitTermination() 实际上并没有进行中断,shutdownNow() 确实,并且正在使用的实现(ThreadPoolExecutor)似乎正在使用Thread.interrupt() 来中断线程。

标签: multithreading java-8 jetty executorservice futuretask


【解决方案1】:

升级到 Jetty 9.4.6 后,这似乎不再是问题。我确实遇到了一些Jetty code that clears the interrupted state of threads,但不清楚这是否是真正的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 2011-07-03
    • 2015-06-02
    • 2014-10-03
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多