Java 8并行流+ anyMatch - 一旦发现匹配,线程是否会被中断?

时间:2014-12-01 19:35:36

标签: java-8

如果我在java 8中有并行流,并且我使用anyMatch终止,并且我的集合有一个与谓词匹配的元素,我试图弄清楚当一个线程处理这个元素时会发生什么。

我知道anyMatch是短路的,因此一旦匹配元素被处理,我就不希望处理更多的元素。我的困惑是关于其他线程发生了什么,可能是在处理元素的中间。我可以想到3个看似合理的场景: a)他们被打断了吗? b)他们是否继续处理他们正在处理的元素,然后,一旦所有线程都无所事事,我得到了我的结果? c)我是否得到了我的结果,但处理其他元素的线程继续处理这些元素(但是一旦完成就不再使用其他元素)?

我有一个长时间运行的谓词,一旦我知道一个元素匹配就很快就终止它。我担心一点,因为我在文档中找不到这些信息,它可能是依赖于实现的东西,这也是很好的。

谢谢

1 个答案:

答案 0 :(得分:29)

经过一些Java源代码的挖掘后,我想我找到了答案。

其他线程会定期检查另一个线程是否找到了答案,如果是,那么它们就会停止工作并取消任何尚未运行的节点。

java.util.Stream.FindOps$FindTask有这种方法:

private void foundResult(O answer) {
        if (isLeftmostNode())
            shortCircuit(answer);
        else
            cancelLaterNodes();
    }

其父类AbstractShortcircuitTask实现shortCircuit,如下所示:

 /**
 * Declares that a globally valid result has been found.  If another task has
 * not already found the answer, the result is installed in
 * {@code sharedResult}.  The {@code compute()} method will check
 * {@code sharedResult} before proceeding with computation, so this causes
 * the computation to terminate early.
 *
 * @param result the result found
 */
protected void shortCircuit(R result) {
    if (result != null)
        sharedResult.compareAndSet(null, result);
}

执行工作的实际compute()方法具有以下重要性:

 AtomicReference<R> sr = sharedResult;
    R result;
    while ((result = sr.get()) == null) {
        ...//does the actual fork stuff here
    }

其中sharedResultshortCircuit()方法更新,因此计算机将在下次检查while循环条件时看到它。

修改 总结如下:

  1. 线程不会中断
  2. 相反,他们会定期检查某人是否找到了答案,并在找到答案时停止进一步处理。
  3. 找到答案后,不会启动任何新主题。