検索

ホームページ  >  に質問  >  本文

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);

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

PHPzPHPz2802日前768

全員に返信(2)返信します

  • 高洛峰

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

    あなたの思考モデルは間違っています。Java8 にはまだ関数型プログラミング機能がありません。
    関数表現の核心は不変性です。これは変数の削除を必要とするのではなく、同等の考え方を確立し、評価プロセスの観点から問題を考えることです。

    マップ内で停止するように求めるなどの例は、設計の範囲外です。マップのセマンティクスにより、すべてのデータを走査することが保証されており、返される型は一貫性があり、同じ長さでなければなりません。また、無謀にラムタイム例外をスローすることも非常に失礼です。

    解決策はいくつかあります。
    オプションまたはいずれかを使用して(これは公式に提供されていないため、自分で取得する必要があります)、マップのセマンティクスを保証するために戻り値の型をラップします(戻り値にエラーを入れますが、型は変更されません。)詳細については百度を確認してください) )

    データにコンテキストがある場合は、マップの代わりに、fold(reduce) を使用して処理します。

    ストリームを使用せず、代わりに休憩に使用してください。重要なのは、問題を解決し、その問題に最適なソリューションを選択することです。場合によっては、steam ソリューションが従来の for および fork/join ほど優れていない場合があります。手動同期通知ほど優れていません。

    また、ストリームの並列性はあなたが思っているほど良くありません。私はしばらくそれを使って遊んだ後、もうほとんど使いません。
    ただし、Java8 には要件を満たす可能性のある completableFuture があります。

    返事
    0
  • PHPz

    PHPz2017-04-18 10:50:40

    カウントダウンラッチ(1)

    例外をキャッチ:

    リーリー

    最後に:

    リーリー

    Java8 のストリームは一度も使用されていません。 。 。

    返事
    0
  • キャンセル返事