【问题标题】:Confused by docs and source of CountedCompleter被 CountedCompleter 的文档和来源弄糊涂了
【发布时间】:2015-04-30 11:28:41
【问题描述】:

这是java.util.concurrent.CountedCompleter 类(JDK 1.8.0_25)的代码片段。

/**
 * If the pending count is nonzero, decrements the count;
 * otherwise invokes {@link #onCompletion(CountedCompleter)}
 * and then similarly tries to complete this task's completer,
 * if one exists, else marks this task as complete.
 */
public final void tryComplete() {
    CountedCompleter<?> a = this, s = a;
    for (int c;;) {
        if ((c = a.pending) == 0) {
            a.onCompletion(s);
            if ((a = (s = a).completer) == null) {
                s.quietlyComplete();
                return;
            }
        }
        else if (U.compareAndSwapInt(a, PENDING, c, c - 1))
            return;
    }
}

这让我很困惑。文档说:“然后类似地尝试完成这个任务的完成者”,但我没有看到在这个任务的完成者上调用任何“完成”;或对它的任何其他调用。

有人学习过这门课吗?这是文档或实施的问题吗?我也可能用错误的方式烹饪它。任何如何正确处理此类的想法都值得赞赏。

【问题讨论】:

  • 我猜,这一切都归功于 a = (s=a).completer 分配,然后在循环的下一次迭代中执行 a.onCompletion(...)
  • 谢谢,看来应该在那里完成;虽然 'onCompletion' 默认是 void 和空的,所以实现类似连接的完成可能不是那么容易和直接。

标签: java concurrency java.util.concurrent forkjoinpool


【解决方案1】:

你感到困惑吗?每个人都很困惑。四年来我一直在写一篇关于 F/J 框架的评论,我可以告诉你复杂程度已经达到了 8u40 的临界水平。这个类存在的原因是因为 join() doesn't work。为了解决 Java8 流的停滞线程,架构师发明了这个类。

这个类的工作方式是为每个 fork() 添加ToPendingCount()。在compute()中,完成后,你tryComplete()。当计数为零时,该方法会调用您的 onCompletion()。有点乱,但如果你的代码很简单,它就可以工作。

您看到的其余代码是针对当前 CountedCompleter 拥有自己的 CountedCompleter 对象链的情况。我的猜测是这可能是用于 parallel.stream 处理。

【讨论】:

  • 您好@edharned,是否可以从这个答案中删除您的个人意见 - 尽管它有点旧。
  • @Kineolyan 类令人困惑,甚至 Doug Lea 在 JavaDoc 中也这么说。这不仅仅是我的选择。截至 2015 年 4 月 30 日,并行流代码尚未最终确定。现在我的猜测是准确的。到底是哪一部分冒犯了你?
  • 你好@edharned,我不能说我被冒犯了。我只是认为最好先给出问题的答案。然后,作为一个侧节点,你可以告知这个 F/J 框架令人困惑,你写了关于它的批评,......但它应该首先关注答案。
  • @Kineolyan 好的,下次我会考虑的。现在我不能改变这么老的(超过两年)的答案。
猜你喜欢
  • 1970-01-01
  • 2022-01-23
  • 2019-01-12
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 2014-08-14
  • 2016-02-16
  • 1970-01-01
相关资源
最近更新 更多