简体   繁体   English

Java 并行流中的异常传播

[英]Exception propagation in Java parallel streams

In Akka in Action book it says that在 Akka in Action 书中,它说

Exceptions are almost impossible to share between threads out of the box, unless you are prepared to build a lot of infrastructure to handle this.开箱即用的线程之间几乎不可能共享异常,除非您准备构建大量基础设施来处理这个问题。

and, as far as I understand, if an exception occurs in a parallel thread it will be propagated to the caller.而且,据我所知,如果在并行线程中发生异常,它将被传播给调用者。 If this mechanism is possible, why isn't it implemented with regular threads?如果这种机制是可能的,为什么不用常规线程来实现呢? Am I missing something?我错过了什么吗?

Edit: I am talking about possibility of something like this:编辑:我说的是这样的可能性:

public static void count() {
    long count = 0;
    try {
        count = IntStream.range(1, 10)
                .parallel()
                .filter(number -> f(number)).count();
    } catch(RuntimeException e) {
        /* handle */
    }
    System.out.println("Count - " + count);
}

public static boolean f(final int number) {
    if(Math.random() < 0.1) {
        throw new RuntimeException();
    }
    return true;
}

parallel() spawns multiple threads and when a RuntimeException is thrown on any of them, that exception is still caught on main thread, which seems to counter that books point. parallel() 产生多个线程,当在其中任何一个上抛出 RuntimeException 时,该异常仍会在主线程上被捕获,这似乎与该书的观点相反。

Edit 2:编辑2:

无法在线程外传播的异常示例

The main difference is that while the individual Stream intermediates can run in parallel, they are only evaluated when the terminal operation is encountered;主要区别在于,虽然各个 Stream 中间体可以并行运行,但它们仅在遇到终端操作时才进行评估; that makes it a virtual join point.这使它成为一个虚拟的连接点。

Ie, the same would be possible with something like即,类似的事情也可能发生

try {
    Thread concurrent = new Thread(runnable);
    concurrent.start();
    concurrent.join();
} catch (ExceptionThrownInThread ex) {}

However, in the general case - and that's pretty much Akka's programming model - you have然而,在一般情况下 - 这几乎是 Akka 的编程模型 - 你有

yourMessenger.registerCallbacks(callbacks);
new Thread(yourMessenger).start(); 

Now, the callbacks will eventually be called from within the thread you created, but there is no structure to wrap around its execution as a whole;现在,回调最终将从您创建的线程中调用,但没有结构可以将其作为一个整体来执行; so who would catch this exception?那么谁会捕捉到这个异常呢?

I don't know Akka enough, but in projectreactor's Publisher s, you can register an error handler, as in我不太了解 Akka,但是在 projectreactor 的Publisher ,您可以注册一个错误处理程序,如

Mono<Result> mono = somethread.createResult().onError(errorHandler);

But again, in the general case it's not trivial.但同样,在一般情况下,这不是微不足道的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM