Search code examples
javareentrantlock

Java ReentrantLock. Unlock method does not reset the header, how to remove the executed thread wrapped in a node?


I am learning Java ReentrantLock source code these days. On the unlock method, it actually do two things: (1) Check if acquire number == release number, if yes, set ExclusiveOwnerThread as null; (2) if (1) is OK, unpark successor;

    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }

My question is, all these opearation did not change the header or dequeue any node in the waiting queue.

Without resetting header or dequeue operation, the waiting queue will grow infinitely as new thread acquire the lock.

Can anyone point out where did I ignore or something wrong with my understanding?


Solution

  • header of the queue operation in acquireQueued method

        final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    //reset header, the second node of queue will be new header
                    setHead(node);
                    //help GC, the old header node will be GC
                    p.next = null;
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }