並列ストリームの作成
parallel() と parallelStream() です。
「並列ストリームの作成」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
並列ストリームの動作
並列ストリームはデータを分割し、複数のスレッドでチャンクを処理してから結果を結合します。目的は大規模な処理でスループットを向上させることです。
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int sum = IntStream.rangeClosed(1, 1000)
.parallel()
.sum();
System.out.println(sum);
}
}既存のストリームに対する parallel()
parallel() を呼び出すと、逐次ストリームが並列ストリームに変わります。パイプラインのどこにでも配置できます。
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5);
int total = nums.stream()
.parallel()
.mapToInt(Integer::intValue)
.sum();
System.out.println(total);
}
}コレクションに対する parallelStream()
Collection.parallelStream() は並列ストリームを直接作成します。stream().parallel() を簡略化したものです。
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> words = List.of("a", "bb", "ccc");
int chars = words.parallelStream()
.mapToInt(String::length)
.sum();
System.out.println(chars);
}
}逐次実行に戻す
sequential() はストリームを単一スレッド実行に戻します。パイプライン全体では、parallel() または sequential() の最後の呼び出しが有効になります。
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int sum = IntStream.rangeClosed(1, 100)
.parallel()
.sequential()
.sum();
System.out.println(sum);
}
}isParallel の確認
isParallel() は、ストリームが並列実行されるかどうかを示します。
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
System.out.println(IntStream.range(0, 10).isParallel());
System.out.println(IntStream.range(0, 10).parallel().isParallel());
}
}結果は同じ、実行方法は異なる
合計のような結合的な演算では、並列ストリームと逐次ストリームは同じ結果を返します。異なるのは実行方法だけです。
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int seq = IntStream.rangeClosed(1, 50).sum();
int par = IntStream.rangeClosed(1, 50).parallel().sum();
System.out.println(seq == par);
}
}共通 ForkJoinPool
並列ストリームは共有された ForkJoinPool.commonPool() を使用します。デフォルトのサイズは、利用可能なプロセッサ数から1を引いた数です。
public class Main {
public static void main(String[] args) {
System.out.println(Runtime.getRuntime().availableProcessors());
}
}スレッドの順序は保証されない
forEach では、チャンクの完了するタイミングが異なるため、並列ストリームが任意の順序で出力することがあります。順序が重要な場合は forEachOrdered を使用します。
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
IntStream.rangeClosed(1, 5)
.parallel()
.forEachOrdered(System.out::println);
}
}縮約で部分結果を結合する
内部では、並列縮約によってチャンクごとの部分結果が計算され、コンバイナーで結合されます。正しく動作させるには、演算が結合的でなければなりません。
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int product = IntStream.rangeClosed(1, 6)
.parallel()
.reduce(1, (a, b) -> a * b);
System.out.println(product);
}
}並列での収集
コレクターフレームワークは、部分コンテナを結合することで並列収集をサポートします。groupingBy は並列でも正しく動作します。
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> words = List.of("apple", "banana", "avocado", "cherry");
Map<Character, List<String>> byFirst = words.parallelStream()
.collect(Collectors.groupingBy(w -> w.charAt(0)));
System.out.println(byFirst);
}
}すべてのストリームが高速になるわけではない
並列化への切り替えは簡単ですが、常に有利とは限りません。データセットが小さい場合や処理が軽い場合は、分割と結合のオーバーヘッドによって並列のほうが遅くなることがあります。
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long count = IntStream.rangeClosed(1, 10)
.parallel()
.filter(n -> n % 2 == 0)
.count();
System.out.println(count);
}
}確認問題
並列ストリームをデフォルトで実行するスレッドプールはどれですか。
まとめ
並列ストリームを作成しました。
parallel()は任意のストリームを変換し、parallelStream()はコレクション向けの簡略形です。sequential()で元に戻せます。最後の呼び出しが有効になります。- 共有された
ForkJoinPool.commonPool()上で実行されます。 - 結合的な演算では逐次実行と結果が一致しますが、順序と速度は保証されません。
よくある質問
「並列ストリームの作成」レッスンは無料ですか?
はい。「並列ストリームの作成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「並列ストリームの作成」で何を学びますか?
parallel() と parallelStream() です。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「並列ストリームの作成」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 並列ストリームの作成
- 並列処理が役立つ場合
- スレッド安全性と副作用
- よくある落とし穴