🔷 はじめに
JavaのStream API
は、コレクション操作を簡潔に記述できる便利な仕組みですが、parallelStream()
を使うことで マルチスレッド処理(並列処理) を手軽に実現できます。
この記事では、parallelStream()
の基本的な使い方から、注意点・パフォーマンスの最適化方法までをわかりやすく解説します。
🔷 StreamとparallelStreamの違い
種類 | 説明 | 特徴 |
---|---|---|
stream() | 通常の逐次処理 | 1スレッドで順次実行される |
parallelStream() | 並列処理 | ForkJoinPoolを使って複数スレッドで分割実行される |
上記のparallelStream()
では、スレッドごとに要素を分割して処理するため、
出力順が異なる(順不同になる)点に注意が必要です。
🔷 並列処理の仕組み(ForkJoinPool)
parallelStream()
は内部的に ForkJoinPool(フォーク・ジョイン・プール)を使用します。
デフォルトでは、Runtime.getRuntime().availableProcessors()
の値(CPUコア数)に応じてスレッド数が自動決定されます。
例えば、4コアCPUの場合は最大4スレッドで同時実行されます。
🔷 実行例:リストの重い処理を並列化する
以下の例では、重い計算を伴う処理を並列実行して速度を比較します。
結果例:
CPUコア数にもよりますが、並列処理では約3倍の高速化が期待できます。
🔷 並列処理時の注意点
注意点 | 内容 |
---|---|
スレッド安全性 | 共有リソースを操作すると競合が発生する可能性あり |
出力順 | forEach()は順序が保証されない(順序を保つにはforEachOrdered()を使用) |
外部API呼び出し | 同時実行でAPI制限に抵触する可能性があるため注意 |
🔷 並列処理の最適化テクニック
-
処理が軽い場合は使わない
-
並列化のオーバーヘッドが大きく、逆に遅くなる場合があります。
-
-
データ量が多い処理に限定する
-
数千件以上の要素を扱う場合に効果的。
-
-
カスタムスレッド数を指定
-
これで並列スレッド数を8に固定できます。
-
🔷 parallelStream()を使うべきケース
✅ CPUバウンド処理(計算中心)
✅ データが多い場合
✅ スレッド安全な処理のみを行う場合
❌ I/Oバウンド処理(ファイル操作・DBアクセス)は非推奨です。
並列化よりも非同期I/O(CompletableFuture
など)を使うほうが効率的です。
🔷 まとめ
項目 | 内容 |
---|---|
メリット | 複雑なスレッド処理を書かずに並列化できる |
デメリット | 順序保証がない・スレッド安全性に注意 |
向いている処理 | CPU負荷の高いループ・数値計算・マッピング処理 |
非推奨の処理 | I/O、同期が必要な共有データ操作 |
parallelStream()
は数行で並列化を実現できる強力なツールですが、
適切な場面で使うことが重要です。
CPUをフル活用して処理時間を短縮したい場面で、ぜひ活用してみてください。