为什么FutureTask在内部不再使用AQS?

时间:2019-04-08 11:08:48

标签: java java-8

为什么相对于jdk7,FutureTask在jdk8中不再在内部使用AQS?

在jdk 8评论中说它已经完成:“避免让用户感到惊讶,因为他们在*取消比赛期间保留了中断状态”

我想了解更多有关该用例的信息,并且如果存在不当行为的示例,此更改将得以解决。

1 个答案:

答案 0 :(得分:5)

请考虑以下情形:

  • 线程A在run()的{​​{1}}方法内
  • 线程B调用FutureTask,成功地将状态从cancel(true)切换到RUNNING(在Java 8之前)
  • 线程A完成CANCELLED方法
  • 仍然位于run()中的线程B中断了线程
  • 线程A(现在位于cancel(true)之外)被虚假中断

新设计通过为尝试中断线程之前设置的FutureTask和之后设置的INTERRUPTING引入不同的状态来解决此问题。然后,在完成时调用以下方法:

INTERRUPTED

请注意,这仍然无法重置线程的中断状态。这仍然是呼叫者的职责,例如/** * Ensures that any interrupt from a possible cancel(true) is only * delivered to a task while in run or runAndReset. */ private void handlePossibleCancellationInterrupt(int s) { // It is possible for our interrupter to stall before getting a // chance to interrupt us. Let's spin-wait patiently. if (s == INTERRUPTING) while (state == INTERRUPTING) Thread.yield(); // wait out pending interrupt … 实现。但是,现在可以保证在取消的情况下,从ExecutorService方法返回时可能的中断已经完成,可以很容易地重置标志。如果没有保证,在取消民主的情况下,有可能在尝试重置中断状态之后发生中断。