In the source code of ConcurrentLinkedQueue in the offer method:
public boolean offer(E e) { checkNotNull(e); final Node<E> newNode = new Node<E>(e); for (Node<E> t = tail, p = t;;) { Node<E> q = p.next; if (q == null) { // p is last node if (p.casNext(null, newNode)) { // Successful CAS is the linearization point // for e to become an element of this queue, // and for newNode to become "live". if (p != t) // hop two nodes at a time casTail(t, newNode); // Failure is OK. return true; } // Lost CAS race to another thread; re-read next } else if (p == q) // We have fallen off list. If tail is unchanged, it // will also be off-list, in which case we need to // jump to head, from which all live nodes are always // reachable. Else the new tail is a better bet. p = (t != (t = tail)) ? t : head; else // Check for tail updates after two hops. p = (p != t && t != (t = tail)) ? t : q; } }
on line 352, this condition is:
p = (p != t && t != (t = tail)) ? t : q;
I know that code should put p in the tail, but why use such complex code? and what does (p != t && t != (t = tail)) mean? what is the difference between t!=(t=tail)) and t!=t ? should it always be false?
Are there any materials that can clearly explain ConcurrentLinkedQueue?
source share