Ответ 1
После некоторого копания через исходный код 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.
ИЗМЕНИТЬ Итак, вкратце:
- Темы не прерываются
- Вместо этого они будут периодически проверять, нашел ли кто-нибудь ответ и прекратит дальнейшую обработку, если ответ был найден.
- После обнаружения ответа новые потоки не будут запущены.