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

new*_*nne 14 java-8

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

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

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

谢谢

dka*_*zel 33

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

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

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

private void foundResult(O answer) {
        if (isLeftmostNode())
            shortCircuit(answer);
        else
            cancelLaterNodes();
    }
Run Code Online (Sandbox Code Playgroud)

它的父类,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);
}
Run Code Online (Sandbox Code Playgroud)

compute()做这项工作的实际方法有这个重要的路线:

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

where sharedResultshortCircuit()方法更新,以便计算机在下次检查while循环条件时看到它.

编辑 所以总结:

  1. 线程不会中断
  2. 相反,他们会定期检查是否有人找到答案,如果找到答案,将停止进一步处理.
  3. 一旦找到答案,就不会启动新的线程.

  • 这是关于实现代码的非常详细的信息,但我建议添加一个最终解决OP问题的摘要,即"会发生什么"→`b` (5认同)