Enq understanding of the method of the AQS

Own dumb, always felt a bit around, finishing next to it ~

private Node enq(final Node node) {
	//自旋锁
    for (;;) {
        //tail默认就是null
        Node t = tail;
        if (t == null) { // Must initialize
            //因为tail默认是null,所以首次一定会进来
            //compareAndSetHead在下面
            //也就是首次一定会把一个新的node设置为head
            if (compareAndSetHead(new Node()))
                //tail=head=new Node()
                tail = head;
            //到这里就是tail和head都会指向new Node
        } else {
            //第二次一定进入else发
            //假如此时进入了一个线程A,这个A已经被封装成了node传进来
            //当前的node的pre指向t,也就是tail,也就是刚才创建的Node,
            //因为第一行就定义了Node t = tail,而t=head=node
            node.prev = t;
            //这里看下面的compareAndSetTail方法
            //把tail节点赋值为新传入的node(Thread A),赋值操作就相当于指向
            if (compareAndSetTail(t, node)) {
                //这里的t指的是原来的tail节点,tail指向一开始的new Node
                //所以就是new Node的next指向新传入的node(Thread A)
                t.next = node;
                return t;
            }
        }
    }
}


private final boolean compareAndSetHead(Node update) {
    //当前的head字段,和null值比对,默认是null,所以相等,所以赋值为update,也就是new node()
    return unsafe.compareAndSwapObject(this, headOffset, null, update);
}


private final boolean compareAndSetTail(Node expect, Node update) {
    //当前的tail字段和期望值exepct,即t进行比较,一定是相等的啊,以为t=tail么,所以更新赋值为update,
    //即新传进来的node(Thread A)
    return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}

The first must be entered if

Here Insert Picture Description

When a new thread to enter when entering else (in fact, no new thread entering or about to enter else's), red is the operating else did

Here Insert Picture Description

to sum up:

Head and tail there is a node, but here I understood as something similar to a pointer, the meaning of their existence but also to maintain this two-way linked list, no practical significance, including the prev and next also.

Quite around, I feel no need to be so thorough understanding of the main idea is to

The first came in the air to create a doubly linked list of nodes, the new node back pass time, two-way back to the beginning of the list to add new nodes, and head and tail always points to the first and the last, are some of the middle switching pointer (I am here for the time being understood as a pointer to it, which is the assignment operator, such as the assignment of the assignment tail and head, prev and the next.)

for (;;) is a spin-lock, non-stop to try to add nodes, but there may be concurrency issues, so by cas way, add, may be the last time a thread to seize the initiative, this time he is still going try, how to keep trying? So resolved through spin lock, of course, if you add the final outcome will pop spin lock by return.

Personally I think that this cas spin lock and operation with very powerful, it is worth learning!

All of the above is my personal understanding, there may be a big problem, I hope not to mislead you, if there are problems also want you to point out promptly.

Published 540 original articles · won praise 3050 · Views 2.5 million +

Guess you like

Origin blog.csdn.net/dataiyangu/article/details/104881208
AQS
AQS