在ConcurrentLinkedQueue的源代码中,在offer
方法中:
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;
}
}
在第352行,有这样的条件:
p = (p != t && t != (t = tail)) ? t : q;
我知道代码是将p放到尾部,但为什么要使用如此复杂的代码? (p != t && t != (t = tail))
是什么意思? t!=(t=tail))
和t!=t
之间的区别是什么?应该总是假的吗?
是否有任何材料可以清楚地解释ConcurrentLinkedQueue?
答案 0 :(得分:0)
这是一个有趣的问题,我asked it more broadly there并得到了一些答案。从我可以阅读的这个主题:
t != (t = tail)
只是一种奇怪的写作方式:
if (t != tail)
t = tail;
简而言之,您要将t
的值与右侧t
的值tail
进行比较。
(所有学分归入Eran,以了解他对该主题及其答案的理解)
完全回答你的问题:
(p != t && t != (t = tail))
表示if p != t and if t != tail t takes the tail value
答案 1 :(得分:-2)
所以我认为另一个线程可以在
的操作之间进行更新t != (t = tail))
正在检查,它正在测试。必须依靠原子才能有用
编辑:
回复Yassine Badache's,downvote 似乎是正确的
t = tail
是一个赋值运算符
也是,
if
语句用于根据条件分支代码,
(x = y)
返回对x的引用,如(通过检查显然已经使用过c的人)
if ((p = fopen(f)) == NULL)
我认为OP是关于Java(或谁)的并发功能的内部实现
编辑:
我觉得这是Java和/或愚蠢的实现中的一个错误