无法在ConcurrentLinkedQueue源代码中获得此条件

时间:2018-01-18 10:28:10

标签: java concurrency

在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?

2 个答案:

答案 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和/或愚蠢的实现中的一个错误