consuming句でスローされた例外(たとえば、forEach
の処理中)でJava 8の並列ストリームがどのように動作するのですか?たとえば、次のコードを入力します。スローされた例外でJava 8の並列ストリームはどのように動作しますか?
final AtomicBoolean throwException = new AtomicBoolean(true);
IntStream.range(0, 1000)
.parallel()
.forEach(i -> {
// Throw only on one of the threads.
if (throwException.compareAndSet(true, false)) {
throw new RuntimeException("One of the tasks threw an exception. Index: " + i);
});
処理された要素はすぐに停止しますか?既に開始された要素が終了するのを待つか?すべてのストリームが終了するのを待っていますか?例外がスローされた後でストリーム要素を処理し始めますか?
いつ復帰しますか?例外の直後ですか?すべての/要素の一部が消費者によって処理された後?
パラレルストリームが例外をスローした後でDo要素が処理され続けますか? (これが起こった場合を見つけた)。
一般的なルールはありますか?並列ストリーム戻りが早く、私はそれは確定的ではないことがわかったかどうかを判断しようとすると
EDIT(15-11-2016)
:
@Test
public void testParallelStreamWithException() {
AtomicInteger overallCount = new AtomicInteger(0);
AtomicInteger afterExceptionCount = new AtomicInteger(0);
AtomicBoolean throwException = new AtomicBoolean(true);
try {
IntStream.range(0, 1000)
.parallel()
.forEach(i -> {
overallCount.incrementAndGet();
afterExceptionCount.incrementAndGet();
try {
System.out.println(i + " Sleeping...");
Thread.sleep(1000);
System.out.println(i + " After Sleeping.");
}
catch (InterruptedException e) {
e.printStackTrace();
}
// Throw only on one of the threads and not on main thread.
if (!Thread.currentThread().getName().equals("main") && throwException.compareAndSet(true, false)) {
System.out.println("Throwing exception - " + i);
throw new RuntimeException("One of the tasks threw an exception. Index: " + i);
}
});
Assert.fail("Should not get here.");
}
catch (Exception e) {
System.out.println("Cought Exception. Resetting the afterExceptionCount to zero - 0.");
afterExceptionCount.set(0);
}
System.out.println("Overall count: " + overallCount.get());
System.out.println("After exception count: " + afterExceptionCount.get());
}
後期リターンないから投げメインスレッドこれにより、例外がスローされた後に多くの新しい要素が処理されました。私のマシンでは、例外がスローされた後に約200個の要素が処理されました。しかし、1000要素すべてが処理されたわけではありません。それでは、ここで何がルールですか?例外がスローされたにもかかわらず、より多くの要素が処理されたのはなぜですか?
(!
)記号を削除すると、メインスレッドに例外がスローされるため、早期返品が返されます。すでに開始された要素だけが処理を終了し、新しい要素は処理されませんでした。早く帰ってきたのはこの場合でした。以前の動作と一致しません。
私はここで何が欠けていますか?
いくつかのドキュメントに基づいていますか? –
@ AlikElzin-kilaka本当はそうではありませんが、これは文書化されていないと思います。私はこれを覚えていますので、このバグを参照している他の質問を読んでください:https://bugs.openjdk.java.net/browse/JDK-8164690 – Eugene
@ AlikElzin-kilaka [これ](http:// mail.openjdk.java.net/pipermail/core-libs-dev/2016-August/042972.html)のディスカッションスレッドで、Eugeneが指摘しているJBSのバグを引き起こしたcore-libs-devメーリングリストに掲載されました。 –