最近在翻看JDK的源码但是奈何基础太差有一处始终想不通。希望大家帮忙解答下共同进步。
ConcurrentLinkedQueue的源码中的offer方法 (checkNotNull(e); final NodenewNode = new Node (e); for (Node t = tail, p = t;;) { Node 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 } )
我的理解是 既然t = p; 那么对p的操作应该等同与对t的操作,那么将newNode设置为p.next不久等同于对t也设置next属性么, 为什么p!=t呢?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
就一个线程在处理的话肯定不会走casTail这句,如果有多个线程呢?
public boolean offer(E e) { checkNotNull(e); final Node newNode = new Node(e);
for (Node t = tail, p = t;;) {
//如果2个线程到这里,一个先把流程走完了
//第二个线程的q开始执行的时候已经不是null了
//所以会走else的分支,修改了p和t的关系
Node 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;
}
}