Home  >  Q&A  >  body text

Java8Stream异常处理

我也是刚用上Java8的Stream,所有的一切都还在照猫画虎的阶段。

在异常处理这块不敢贸然前进,因为我看到某篇文的这样一段话

在单线程环境中,使用捕获受检异常并重新抛出非受检异常的方法是可行的。但是在多线程环境这样用,就存在一些风险。

多线程环境中,Lambda表达式中发生的错误会被自动传递到主线程中。这会带来两个问题:

这不会停止其他正在并行执行的Lambda表达式。
如果有多个线程抛出了异常,在主线程中却只能捕获到一个线程中的异常。如果这些异常信息都很重要的话,那么更好的方法是在Lambda表达式中就进行异常处理并将异常信息作为结果的一部分返回到主线程中。

我现在是用的Stream流的Map方法,当然用的是并发,想在map里的方法里只要有一个出错就让他停下来,不运行其他的。。这个需求该怎么搞。。

paths.stream()
    .map(path -> {
        try {
            return new File(path).getCanonicalPath();
        } catch(IOException ex) {
            throw new RuntimeException(ex);
        }
    })
    .forEach(System.out::println);

我用了这种方法确实停下来了,那还有什么好的方法,或者说是否有何问题,这样的话就拿不到具体哪个线程有问题了吧

PHPzPHPz2744 days ago738

reply all(2)I'll reply

  • 高洛峰

    高洛峰2017-04-18 10:50:40

    Your thinking model is wrong. Map filter is not syntactic sugar. Java8 still has functional programming capabilities.
    The core of functional expression is invariance. This is not to require the elimination of variables, but to establish an equivalent thinking and think about the problem in terms of evaluation > process.

    Your example, such as asking to stop in the map, is outside the design, because the semantics of the map guarantee that it will traverse all the data, and the returned type must be consistent and of the same length. It is also very inelegant to throw a rumtime exception rashly.

    There are several solutions.
    Use optional or either (this is not officially provided, you need to get one yourself) to wrap your return type to ensure map semantics (put the error in the return value, but the type remains unchanged. You can check Baidu for details) )

    If your data has context, use fold(reduce) to process it instead of map.

    Don’t use stream and use for break instead. Programming is actually programming. The key is to solve the problem and choose the best solution for the problem. Sometimes the steam solution is not as good as the traditional for, and fork/join is not as good as manual sync notify.

    Also, the parallelism of stream is not as good as you think. I abuse copyonwrite. After playing with it for a while, I almost never use it again.
    However, java8 has a completableFuture that may meet your requirements.

    reply
    0
  • PHPz

    PHPz2017-04-18 10:50:40

    CountDownLatch(1)

    catch exception:

    CountDownLatch.countDown();

    Finally:

    CountDownLatch.await();
    xxx.stop();
    

    Java8’s Stream has never been used. . .

    reply
    0
  • Cancelreply