【问题标题】:Can't get this condition in ConcurrentLinkedQueue source code [duplicate]在 ConcurrentLinkedQueue 源代码中无法获得此条件 [重复]
【发布时间】:2018-06-27 09:25:48
【问题描述】:

在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 &amp;&amp; t != (t = tail))是什么意思? t!=(t=tail))t!=t 有什么区别?它应该总是假的吗?

有什么资料可以把ConcurrentLinkedQueue解释清楚吗?

【问题讨论】:

  • ttail的类型有哪些?
  • Tailt 在源代码中是 Node&lt;E&gt; 类型。

标签: java concurrency


【解决方案1】:

这是一个有趣的问题,我asked it more broadly there 得到了一些答案。从我能读到的关于这个主题的内容:

t != (t = tail) 只是一种奇怪的写法:

if (t != tail)
    t = tail;

简而言之,您将t 的值与分配给右侧t 的值进行比较,此处为tail

(所有学分都转到Eran他对主题的理解和他的回答)

所以要完整回答你的问题:

  • 我不知道他们为什么使用如此复杂的代码。
  • (p != t &amp;&amp; t != (t = tail)) 表示 if p != t and if t != tail t takes the tail value
  • 差异说明
  • 它不应该总是错误的(显然)

【讨论】:

    【解决方案2】:

    所以我认为另一个线程可能会在操作之间更新

    t != (t = tail))
    

    正在检查,并且正在为此进行测试。它必须以某种方式依赖原子才能有用

    编辑:

    回复 Yassine Badache 的意见,投反对票 这似乎是正确的

    t = tail
    

    是赋值运算符

    还有

    if
    

    语句用于根据条件分支代码,并且

    (x = y)
    

    返回对 x 的引用,如(通过检查任何曾经使用过 c 的人都可以看出)

    if ((p = fopen(f)) == NULL)
    

    我认为 OP 是关于 Java(或任何人)的并发功能的内部实现

    编辑:

    我认为这是 Java 实现中的一个错误和/或愚蠢

    【讨论】:

    • 这没有回答问题。 OP 询问这是什么意思,这和t != t 有什么区别。
    • @YassineBadache 您的回答可能更适用于 c++,我认为 Java 比较了参考资料,可能没有太多其他内容。问题是并发性。您断言比较该值是完全错误的。你需要实现和使用 isEqual() 方法
    • @YassineBadache 还有你的代码: if (t != tail) t = tail;倒退了,完全错了
    • 我认为第一步分配 t = tail 然后执行 t! = 吨。我对吗?结果总是假的
    • 尝试运行int t=1; int tail=2;if (t != (t = tail)) System.out.println ("not equal");,正如一些人已经推荐的那样。你会看到这个答案的顺序是倒退的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 2015-08-26
    • 1970-01-01
    • 2012-01-23
    • 2018-05-25
    • 2013-06-28
    • 1970-01-01
    相关资源
    最近更新 更多