web-dev-qa-db-ja.com

JavaEEコンテナ内でJava 8つの並列ストリームを使用することはお勧めしませんか?

Java EEコンテナでスレッドを生成することはお勧めしません 。 Java EE内でスレッドを生成する可能性のある Java 8並列ストリーム を使用することもお勧めしませんか?

32
Luís Bianchin

[〜#〜] edit [〜#〜]andrepnhからの代替回答を参照してください。以下は計画だったかもしれませんが、実際にはそのように実行されたようには見えません。


コメントで言及されている lambda-devメーリングリストのディスカッション からの読み方:スレッドの生成方法は落胆していませんが、Java EEコンテキスト。

リンクされたディスカッションから:

Java EEの並行性の人々はすでにこれについて話し合っていましたが、現在の結果は、EEコンテナ内から実行すると、FJPがシングルスレッド(呼び出し元コンテキストでさえ)の実行に優雅に低下することです。

したがって、両方のコンテキストで実行されるプロシージャまたはライブラリで並列ストリームを安全に使用できます。 SE環境で実行すると、魔法の並列シェナニガンで作成されますが、EE環境で実行すると、シリアル実行に正常に低下します。

注:上で引用したフレーズは未来形です-誰かがいくつかの決定的なドキュメントの引用を持っていますか?

12
Shorn

注意してください、シングルスレッドへの優雅な劣化は利用できません。また、Shornの回答とそのメーリングリストの議論のせいだと思いましたが、 この質問 を調べている間ではなかったことがわかりました。このメカニズムはJava EE 7仕様ではなく、Glassfish 4.1にもありません。別のコンテナーがそれを行ったとしても、移植性はありません。

次のメソッドを呼び出すことで、これをテストできます。

@Singleton
public class SomeSingleton {
    public void fireStream() {
        IntStream.range(0, 32)
            .parallel()
            .mapToObj(i -> String.format("Task %d on thread %s", 
                i, Thread.currentThread().getName()))
            .forEach(System.out::println);
    }
}

そして、次のようなものが得られます。

Info:   Task 20 on thread http-listener-1(4)
Info:   Task 10 on thread ForkJoinPool.commonPool-worker-3
Info:   Task 28 on thread ForkJoinPool.commonPool-worker-0
...

Glassfish 4.1.1のソースコードも確認しましたが、ForkJoinPoolForkJoinWorkerThreadFactory、またはForkJoinWorkerThreadの使用は1回ではありません。

多くのフレームワークがjdk8機能を活用するため、このメカニズムをEE 8に追加することもできますが、それが仕様の一部であるかどうかはわかりません。

11
andrepnh