検索
ホームページ運用・保守安全性ParallelStream 使用の落とし穴を解決する方法

たとえば、次のコード スニペットを使用すると、人々は詩を読むように読むことができます。しかし、使い方を誤ると致命傷になる可能性があります。

List<integer> transactionsIds = widgets.stream()              .filter(b -> b.getColor() == RED)              .sorted((x,y) -> x.getWeight() - y.getWeight())              .mapToInt(Widget::getWeight)              .sum();</integer>

このコードには、ストリームという重要な機能があります。これを使用すると、通常のリストをストリームに変換し、パイプラインを使用してリストを処理できます。全体として、私が使用したものはすべて良いと言っています。

これらの関数にあまり詳しくありませんか?「Map と flatMap はどこにでもありますが、それらは何を意味しますか?」を参照してください。

ここで質問があります

If ストリームをParallelStreamに置き換えるとどうなりますか?

文字通りの意味によれば、ストリームはシリアルからパラレルに変わります。

これが並行状況であることを考慮すると、スレッドの安全性の問題が発生することは明らかです。ただし、このトピックは基本すぎるため、ここで議論しているのはスレッドセーフなコレクションを使用する必要性ではありません。今日では、スレッドセーフでない状況でスレッドセーフなコレクションを使用する方法を学ぶことは、必須のスキルとなっています。

今回の落とし穴は、並列ストリーミングのパフォーマンスの問題です。

コードに語らせます。

次のコードは、同時に 8 つのスレッドを有効にし、すべてのスレッドがデータ計算に並列ストリームを使用します。実行ロジックでは、各タスクを 1 秒間スリープさせて、時間のかかる一部の I/O リクエストの待機をシミュレートできるようにします。

ストリームを使用すると、プログラムは 30 秒後に戻りますが、これは並列ストリームであり、このタイトルにふさわしいため、プログラムは 1 秒以上で戻ることが予想されます。

テストの結果、タスクが完了するまでに長時間待機していることが判明しました。

static void paralleTest() {     List<integer> numbers = Arrays.asList(             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,             20, 21, 22, 23, 24, 25, 26, 27, 28, 29     );     final long begin = System.currentTimeMillis();     numbers.parallelStream().map(k -> {         try {             Thread.sleep(1000);             System.out.println((System.currentTimeMillis() - begin) + "ms => " + k + " \t" + Thread.currentThread());         } catch (InterruptedException e) {             e.printStackTrace();         }         return k;     }).collect(Collectors.toList()); }  public static void main(String[] args) { //    System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "20");     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start();     new Thread(() -> paralleTest()).start(); }</integer>

pit

実際、このコードは異なるマシンで実行すると、実行にかかる時間も異なります。

並列処理であるため、ある程度の並列処理が必要です。並列度が低すぎるとその能力が発揮されず、並列度が高すぎるとコンテキスト切り替え時間が無駄になります。私は、スレッド プールのさまざまなパラメータやさまざまなチューニングを暗記している多くの上級開発者が、敢えて見て見ぬふりをして、I/O 集中型のビジネスでParallelStream を使用していることに気づき、非常にイライラしました。

この程度の並列性を理解するには、具体的な構築方法を確認する必要があります。 ForkJoinPool クラスで次のようなコードを見つけます。

try {  // ignore exceptions in accessing/parsing properties     String pp = System.getProperty         ("java.util.concurrent.ForkJoinPool.common.parallelism");     if (pp != null)         parallelism = Integer.parseInt(pp);     fac = (ForkJoinWorkerThreadFactory) newInstanceFromSystemProperty(         "java.util.concurrent.ForkJoinPool.common.threadFactory");     handler = (UncaughtExceptionHandler) newInstanceFromSystemProperty(         "java.util.concurrent.ForkJoinPool.common.exceptionHandler"); } catch (Exception ignore) { }  if (fac == null) {     if (System.getSecurityManager() == null)         fac = defaultForkJoinWorkerThreadFactory;     else // use security-managed default         fac = new InnocuousForkJoinWorkerThreadFactory(); } if (parallelism  MAX_CAP)     parallelism = MAX_CAP;

ご覧のとおり、並列度は次のパラメータによって制御されます。このパラメータが取得できない場合は、デフォルトで CPU 数 - 1 の並列処理が使用されます。

ご覧のとおり、この機能はコンピューティング集約型のビジネス向けに設計されています。割り当てたタスクが多すぎると、並列実行がシリアルのような効果に低下します。

-Djava.util.concurrent.ForkJoinPool.common.parallelism=N

-Djava.util.concurrent.ForkJoinPool.common.Parallelism=N を使用して初期サイズを設定した場合でも、依然として問題が発生します。

一度設定されると、並列処理変数は Final に設定され、変更が禁止されます。つまり、上記のパラメータは 1 回だけ有効になります。

Zhang San は次のコードを使用して、並列処理サイズを 20 に設定します。

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "20");

Li Si も同様にこの値を 30 に設定した可能性があります。プロジェクトでどの値が使用されているかを判断するには、クラス情報をロードする方法を JVM に問い合わせる必要があります。

この方法はあまり信頼性がありません。

#解決策

外部の forkjoinpool を提供する、つまり送信方法を変更することで、さまざまなタイプのタスク分離を実現できます。

コードは次のとおりです。タスクの分離は、明示的にコードを送信することで実現できます。

ForkJoinPool pool = new ForkJoinPool(30);  final long begin = System.currentTimeMillis(); try {     pool.submit(() ->             numbers.parallelStream().map(k -> {                 try {                     Thread.sleep(1000);                     System.out.println((System.currentTimeMillis() - begin) + "ms => " + k + " \t" + Thread.currentThread());                 } catch (InterruptedException e) {                     e.printStackTrace();                 }                 return k;             }).collect(Collectors.toList())).get(); } catch (InterruptedException e) {     e.printStackTrace(); } catch (ExecutionException e) {     e.printStackTrace(); }
このように、シナリオごとに異なる並列度を持たせることができます。この方法による手動リソース管理と CountDownLatch には類似点があり、同じ目的を持っています。

以上がParallelStream 使用の落とし穴を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい