有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

为什么FutureTask不再在jdk8内部使用AQS而不是jdk7

jdk 8评论中说它已经完成了:“避免让用户惊讶于在*取消竞争期间保留中断状态”

我想知道更多关于这个用例的信息,如果有一个不希望出现的行为的例子,这个改变会修复


共 (1) 个答案

  1. # 1 楼答案

    考虑下面的场景:

    • 线程A位于FutureTaskrun()方法内
    • 线程B调用cancel(true),它成功地将状态从RUNNING切换到CANCELLED(Java8之前)
    • 线程A完成了run()方法
    • 线程B仍然在cancel(true)内,会中断线程
    • 线程A,现在在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实现。但是现在可以保证,在取消的情况下,当从run()方法返回时,潜在的中断已经完成,因此很容易重置标志。如果没有这种保证,在快速取消的情况下,中断可能发生在尝试重置中断状态之后