1

As code shown below in FutureTask.java (Jdk1.7):

/**
 * Tries to unlink a timed-out or interrupted wait node to avoid
 * accumulating garbage.  Internal nodes are simply unspliced
 * without CAS since it is harmless if they are traversed anyway
 * by releasers.  To avoid effects of unsplicing from already
 * removed nodes, the list is retraversed in case of an apparent
 * race.  This is slow when there are a lot of nodes, but we don't
 * expect lists to be long enough to outweigh higher-overhead
 * schemes.
 */
private void removeWaiter(WaitNode node) {
    if (node != null) {
        node.thread = null;
        retry:
        for (;;) {          // restart on removeWaiter race
            for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
                s = q.next;
                if (q.thread != null)
                    pred = q;
                else if (pred != null) {
                    pred.next = s;
                    if (pred.thread == null) // check for race
                        continue retry;
                }
                else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                      q, s))
                    continue retry;
            }
            break;
        }
    }
}

We can find that there has two comments:

check for race

And

restart on removeWaiter race


This is a simple image that shown the state change in removeWaiter:

enter image description here

There is my understanding and question:

Race condition: When a thread successfully finds the pred node, and another thread try to remove pred node, race happend.

In my opnion: q.next,q.thread and pred.thread are both volitile,so if current thread continue race with others threads, the result will also valid.

Question: Why Doug Lea choose restart race rather than continue race, or is there something wrong for my opinion?

Hello World
  • 129
  • 7

0 Answers0