入力を取得し、その上に並列ストリームを適用したいので、リストとして出力します。入力は、ストリームを適用できるリストまたはコレクションです。
ここでの懸念は、マップとして出力したい場合、Javaは
_list.parallelStream().collect(Collectors.toConcurrentMap(args))
_
しかし、出力としてリストを提供するスレッドセーフな方法で並列ストリームから収集するオプションはありません。使用するオプションがもう1つあります
list.parallelStream().collect(Collectors.toCollection(<Concurrent Implementation>))
このようにして、collectメソッドでさまざまな同時実装を提供できます。ただし、Java.util.concurrentにはCopyOnWriteArrayList List実装のみが存在すると思います。ここではさまざまなキュー実装を使用できますが、それらはリストのようにはなりません。ここで私が意味するのは、リストを取得するための回避策があるということです。
リストとして出力したい場合の最良の方法は何ですか?
注:これに関連する他の投稿を見つけることができませんでした。参考資料があれば参考になります。
収集されるデータの受信に使用されるCollection
オブジェクトは、同時である必要はありません。単純なArrayList
を指定できます。
これは、パラレルストリームからの値のコレクションが実際に単一のCollection
オブジェクトに収集されないためです。各スレッドは独自のデータを収集し、すべてのサブ結果はマージされて単一の最終Collection
オブジェクトになります。
これはすべて Collector
javadocで十分に文書化されており、Collector
は collect()
に与えるパラメーターです。 メソッド:
<R,A> R collect(Collector<? super T,A,R> collector)
But there is no option that I can see to collect from parallel stream in thread safe way to provide list as output
。これはまったく間違っています。
ストリームのポイントは、スレッドセーフでないコレクションを使用して、完全に有効なスレッドセーフな結果を達成できることです。これは、ストリームがどのように実装されているかによるものです(これはストリームの設計の重要な部分でした)。 Collector
は、各ステップで新しいインスタンスを作成するメソッドsupplier
を定義していることがわかります。それらのインスタンスはそれらの間でマージされます。
したがって、これは完全にスレッドセーフです。
Stream.of(1,2,3,4).parallel()
.collect(Collectors.toList());
このストリームには4つの要素があるため、ArrayList
の4つのインスタンスが作成され、最後に1つの結果にマージされます(少なくとも4つのCPUコアを想定)
反対側でtoConcurrent
のようなメソッドは単一の結果コンテナを生成し、すべてのスレッドは結果をそこに入れます。