@dj Zheng Doujiu I don’t know if this is correct. It is designed based on debug, and the correct output is t instead of node. I don’t know if you also express this meaning
Pure enq feels like it has nothing to do with concurrency, it’s just the establishment of a doubly linked list. The linked list in Java is no different from that in C++, except that Java encapsulates pointer into reference, which actually still plays the role of pointer. Node t can be viewed abstractly as the node before the newly inserted node, which is first in, first out in the queue. Naturally, the new node is inserted at the end of the queue, so Node t = tail. Ignoring the situation of an empty queue, if a node joins a queue, the pre and next of the new node must be processed first, so node.pre = tail; node.next = null;. Then point the next of the previous node to the new node, that is, node, t.next = node. Next, consider the empty queue. Here, the queue is forcibly initialized with a new Node(). At this time, tail == head. As for not inserting the newly inserted node, I don't understand the reason for this. Intuitively, compareAndSetHead(node) is more normal. Of course, it does not directly change the pre and next values like a single-threaded queue, but is encapsulated into the comapreAndSet* function. Multi-threaded mutual exclusion should be maintained here.
Ha, you probably can’t understand that enq method now. If you haven’t learned it specifically, I guess not many people can understand it. Learning lock-free synchronization is a very advanced part of multi-threading.
@dj Zheng Doujiu I don’t know if this is correct. It is designed based on debug, and the correct output is t instead of node. I don’t know if you also express this meaning
Pure enq feels like it has nothing to do with concurrency, it’s just the establishment of a doubly linked list. The linked list in Java is no different from that in C++, except that Java encapsulates pointer into reference, which actually still plays the role of pointer.
Node t can be viewed abstractly as the node before the newly inserted node, which is first in, first out in the queue. Naturally, the new node is inserted at the end of the queue, so Node t = tail. Ignoring the situation of an empty queue, if a node joins a queue, the pre and next of the new node must be processed first, so node.pre = tail; node.next = null;. Then point the next of the previous node to the new node, that is, node, t.next = node. Next, consider the empty queue. Here, the queue is forcibly initialized with a new Node(). At this time, tail == head. As for not inserting the newly inserted node, I don't understand the reason for this. Intuitively, compareAndSetHead(node) is more normal.
Of course, it does not directly change the pre and next values like a single-threaded queue, but is encapsulated into the comapreAndSet* function. Multi-threaded mutual exclusion should be maintained here.
Ha, you probably can’t understand that enq method now. If you haven’t learned it specifically, I guess not many people can understand it. Learning lock-free synchronization is a very advanced part of multi-threading.