简体   繁体   English

FutureTask 实现重新读取 state 以防止泄漏中断

[英]FutureTask Implementation re-read state to prevent leaked intterupts

Here is the implementation of some methods of FutureTask in Java:下面是Java中FutureTask的一些方法的实现:

run method: run方法:

public void run() {
    if (state != NEW ||
        !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                     null, Thread.currentThread()))
        return;
    try {
        Callable<V> c = callable;
        if (c != null && state == NEW) {
            V result;
            boolean ran;
            try {
                result = c.call();
                ran = true;
            } catch (Throwable ex) {
                result = null;
                ran = false;
                setException(ex);
            }
            if (ran)
                set(result);
        }
    } finally {
        // runner must be non-null until state is settled to
        // prevent concurrent calls to run()
        runner = null;
        // state must be re-read after nulling runner to prevent
        // leaked interrupts
        int s = state;
        if (s >= INTERRUPTING)
            handlePossibleCancellationInterrupt(s);
    }
}

cancel Method: cancel方法:

public boolean cancel(boolean mayInterruptIfRunning) {
    if (!(state == NEW &&
          UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
              mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
        return false;
    try {    // in case call to interrupt throws exception
        if (mayInterruptIfRunning) {
            try {
                Thread t = runner;
                if (t != null)
                    t.interrupt();
            } finally { // final state
                UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
            }
        }
    } finally {
        finishCompletion();
    }
    return true;
}

handlePossibleCancellationInterrupt method: handlePossibleCancellationInterrupt方法:

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

    // assert state == INTERRUPTED;

    // We want to clear any interrupt we may have received from
    // cancel(true).  However, it is permissible to use interrupts
    // as an independent mechanism for a task to communicate with
    // its caller, and there is no way to clear only the
    // cancellation interrupt.
    //
    // Thread.interrupted();
}

I know these methods are implemented this way to prevent the run method to finish before interrupting the thread in cancel method finished and the state has changed from interrupting to interrupted but I can't understand two things:我知道这些方法是以这种方式实现的,以防止 run 方法在cancel方法完成中断线程之前完成,并且 state 已从interrupting变为interrupted ,但我无法理解两件事:

Why these lines of code in run method:为什么运行方法中有这些代码行:

int s = state;
if (s >= INTERRUPTING)
    handlePossibleCancellationInterrupt(s);

could not be changed to this one:无法更改为此:

if (state == INTERRUPTING)
    handlePossibleCancellationInterrupt(state);

So I can't understand two things:所以我无法理解两件事:

  1. What is the effect of this statement int s = state这个语句的作用是什么int s = state
  2. Why state >= INTERRUPTING statement can not be changed to this one state == INTERRUPTING为什么state >= INTERRUPTING语句不能改成这一条state == INTERRUPTING

1. Effect of int s = state 1. int s = state

state being a volatile variable, must be the predominant reason for assigning it to s . state是一个volatile变量,必须是将其分配给s主要原因。 This way, we can avoid an additional costlier volatile read access within the if statement.这样,我们可以避免在if语句中进行额外的成本更高的易失性读取访问。

The links here and here discusses about volatile read performance. 此处此处的链接讨论了易失性读取性能。

2. state >= INTERRUPTING 2. state >= INTERRUPTING

May be initially there were discussions to reset the interrupted status of the thread in handlePossibleCancellationInterrupt() .最初可能有讨论在handlePossibleCancellationInterrupt()中重置线程的interrupted状态。

Below block commented in handlePossibleCancellationInterrupt()下面的块在handlePossibleCancellationInterrupt()中注释

 // We want to clear any interrupt we may have received from // cancel(true). However, it is permissible to use interrupts // as an independent mechanism for a task to communicate with // its caller, and there is no way to clear only the // cancellation interrupt. // // Thread.interrupted();

Clearing the interrupt should have happen, even in case the state is INTERRUPTED .即使 state 是INTERRUPTED ,也应该清除中断。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无需重启即可重新读取配置 - Re-read configuration without restart Kafka与Java:如何重新读取数据 - Kafka with Java: how to re-read data 如何强制Android重新读取GPS位置? - How enforce Android to re-read GPS position? 如何重置偏移值重新读取kafka主题 - How to reset the offset value to re-read the kafka topic 调用IOUtils.copy后如何重新读取InputStream? - How to re-read an InputStream after calling IOUtils.copy? maven 会为不同的生命周期阶段重新读取 pom 文件吗? - Will maven re-read a pom file for different lifecycle phases? 如何读取文件内容,写入outputstream以及重新读取并存储在Java内存中的字符串变量中 - how to read contents of file, write to outputstream and the re-read and Store in a string variable in memory in java 如何将字符串中的新行字符插入PrintStream,然后使用扫描程序重新读取该文件 - how to insert a new line character in a string to PrintStream then use a scanner to re-read the file 如何将字符串保存在本地缓冲区中,以便扫描程序可以重新读取它? - How to save a String in local buffer so that it can be re-read by Scanner? 重新阅读该方法应该是什么,我的代码看起来正确吗? - Re-read what the method is supposed to be, do my code look about right?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM