非並行データ構造ソースのストリームを使用するための非干渉要件は、実行中にデータ構造の要素の状態を変更できないことを意味しますか?ストリームパイプライン(ソースデータ構造自体を変更することはできません) (質問1)セクションでJava 8ストリームでの非干渉の正確な意味
約non-interferenceは、ストリームパッケージの説明では、その言った: 「ほとんどのデータ・ソースの場合、干渉を防止することは、データソースがの実行中に全てで修飾されていないことを確実にする手段ストリームパイプライン。
この節では要素の状態の変更については言及していませんか?
たとえば、「シェイプ」がスレッドセーフではないコレクション(ArrayList
など)であると仮定すると、以下のコードで干渉が発生していると考えられますか?それは正確でなければならないので(質問2)
shapes.stream()
.filter(s -> s.getColor() == BLUE)
.forEach(s -> s.setColor(RED));
この例は、(控えめに言って)reliable sourceから取られます。 しかし、stream()
をparallelStream()
に変更した場合でも、それはまだ安全で正しいでしょうか? (質問3)
もう一方の信頼できる情報源であるNaftalin Mauriceの "Mastering Lambdas"は、パイプライン操作によって要素の状態(値)を変更することが実際には干渉であることを明確にしています。非干渉(3.2.3)に関するセクションから:
"ストリームのルールは、パイプライン操作だけでなく、どのスレッドでも要素の値を変更するなど、ストリームソースの変更を禁止しています"
本書の内容が正しい場合は、ストリームAPIを使用して要素の状態を変更することはできません(forEach
を使用)。通常のイテレータを使用するか、またはIterable.forEach
)? (質問4)
つまり、「干渉」はより高いレベルにあります。ストリーム要素を変更するアクションは、同じ要素を同時に変更しているときに干渉しますが、別個のオブジェクトを変更しているときは干渉しません。同様に、 'ArrayList'自体はスレッドセーフではないが、' ArrayList'が同時のシナリオで正しく使用される可能性を排除するものではない。それはすべてについてです、*どのように使用されていますか? – Holger
あなたの明確で詳細な答えをお送りいただきありがとうございます。コレクション内の変更可能な要素を維持することは一般的な作業であり、イテレータを使用して行われるコレクションの多くの操作は要素の状態を変更する必要があるため、実際には気になります。私たちが安全に行うことができなければ、ストリームを(少なくともパラレルストリームの場合は)あまり役に立たないでしょう。 – Shay
Tagirステートフルラムダは、ストリームパッケージ(およびあなたが言及したリンク)で、結果がストリームパイプラインの実行中に変更される可能性のある状態に依存するものとして定義されていることに注意してください。 – Shay