Why "fast path" is faster than full enq in AQS

Nathaniel Wen:

Hi, everyone:
I'm reading the source code of "AbstractQueuedSynchronizer", getting a little confused of the reason why "fast path" is faster than full enq in the comment "Try the fast path of enq; backup to full enq on failure".


David Holmes:

What version of the code are you looking at? I can’t see anything like that in current OpenJDK sources.


Nathaniel Wen:

My JDK version is 1.8

private Node addWaiter(Node mode) {
    Node node = new Node(Thread.currentThread(), mode);
    // Try the fast path of enq; backup to full enq on failure
    Node pred = tail;
    if (pred != null) {
        node.prev = pred;
        if (compareAndSetTail(pred, node)) {
            pred.next = node;
            return node;
        }
    }
    enq(node);
    return node;
}

David Holmes:

The fast path just does a direct enqueue to the existing tail. The enq(), in the worst case, has to initialize the queue, and in general deals with contention due to concurrent enqueue attempts.

The code is different now.


Nathaniel Wen:

The full enq will loop only once when there is no contention and the tail isn't null. The reason why "fast-path" is faster is because in most cases the tail isn't null. So "if (tail != null)" is more efficient than "if (tail == null) ... else ..." in this very case, am I right?


David Holmes:

The old structure was intended to be more amenable to inlining the fast-path code IIRC. The new code doesn’t bother AFAICS.


Martin Buchholz:

Alternatively: initializeSyncQueue is now a separate cold-code method.

(All of this is unlikely to matter much)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。