如果我在java 8中有并行流,并且我使用anyMatch终止,并且我的集合有一个与谓词匹配的元素,我试图弄清楚当一个线程处理这个元素时会发生什么。
我知道anyMatch是短路的,因此一旦匹配元素被处理,我就不希望处理更多的元素。我的困惑是关于其他线程发生了什么,可能是在处理元素的中间。我可以想到3个看似合理的场景: a)他们被打断了吗? b)他们是否继续处理他们正在处理的元素,然后,一旦所有线程都无所事事,我得到了我的结果? c)我是否得到了我的结果,但处理其他元素的线程继续处理这些元素(但是一旦完成就不再使用其他元素)?
我有一个长时间运行的谓词,一旦我知道一个元素匹配就很快就终止它。我担心一点,因为我在文档中找不到这些信息,它可能是依赖于实现的东西,这也是很好的。
谢谢
答案 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
}
其中sharedResult
由shortCircuit()
方法更新,因此计算机将在下次检查while循环条件时看到它。
修改强> 总结如下: