1

Here is the implementation of some methods of FutureTask in Java:

run method:

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:

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:

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:

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
  2. Why state >= INTERRUPTING statement can not be changed to this one state == INTERRUPTING
Tashkhisi
  • 2,070
  • 1
  • 7
  • 20
  • FYI, your source code looks outdated. [Here is Java 11](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/concurrent/FutureTask.java), and [here is Java 16 pre-release](https://github.com/openjdk/jdk16/blob/master/src/java.base/share/classes/java/util/concurrent/FutureTask.java). – Basil Bourque Dec 14 '20 at 06:20
  • @BasilBourque Where is the difference they are exactly the same. – Tashkhisi Dec 14 '20 at 07:28
  • Not the same. Yours calls `UNSAFE`. Java 11 & 16 do not. And there may be other changes, such as [8197531: Miscellaneous changes imported from jsr166 CVS 2018-04](https://github.com/openjdk/jdk/commit/cdd36df3637b1bd1f1528a82a7efb24c39dad70a). – Basil Bourque Dec 14 '20 at 07:33
  • Thanks for your precious information, but the part I mentioned in the question are the same. I mean this part `int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s);` – Tashkhisi Dec 14 '20 at 07:38

1 Answers1

1

1. Effect of int s = state

state being a volatile variable, must be the predominant reason for assigning it to s. This way, we can avoid an additional costlier volatile read access within the if statement.

The links here and here discusses about volatile read performance.

2. state >= INTERRUPTING

May be initially there were discussions to reset the interrupted status of the thread in handlePossibleCancellationInterrupt().

Below block commented in 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.

Prasanna
  • 2,390
  • 10
  • 11