Java 8 並列ストリームのカスタマイズ可能なスレッド プール
並列ストリーム内のスレッド リソース割り当てを制御すると、アプリケーションのパフォーマンスとモジュール性が向上します。ただし、Java 8 で特定のストリーム操作にカスタム スレッド プールを指定する方法は依然として不明です。
この記事では、この問題を調査し、並列ストリームにおける共有スレッド プールの制限を克服する解決策を提供します。
問題ステートメント
並列ストリームを利用するサーバー アプリケーションを考えてみましょう。 1 つのモジュール内の遅いタスクが他のモジュールに影響を与えるのを防ぐために、スレッド プールの区画化が望まれます。ただし、標準の並列ストリーム実装では、すべての操作に共有スレッド プールが採用されています。
次のコード スニペットに示されているように、侵害されたタスクは他のスレッドを無期限に遅延させます。
// CPU-intensive tasks in separate threads leveraging parallel streams ExecutorService es = Executors.newCachedThreadPool(); es.execute(() -> runTask(1000)); // Incorrect task es.execute(() -> runTask(0)); es.execute(() -> runTask(0)); es.execute(() -> runTask(0)); es.execute(() -> runTask(0)); es.execute(() -> runTask(0));
解決策
指定された fork-join プール内で並列操作を実行するには、それをタスク内のタスクとして使用します。プール。これにより、操作が共有プールから分離されます:
final int parallelism = 4; ForkJoinPool forkJoinPool = null; try { forkJoinPool = new ForkJoinPool(parallelism); final List<Integer> primes = forkJoinPool.submit(() -> { // Parallel task here, for example: return IntStream.range(1, 1_000_000).parallel() .filter(PrimesPrint::isPrime) .boxed() .collect(Collectors.toList()); }).get(); System.out.println(primes); } catch (Exception e) { throw new RuntimeException(e); } finally { if (forkJoinPool != null) { forkJoinPool.shutdown(); } }
この手法は、ForkJoinTask.fork() の動作を利用します: 「現在のタスクが実行されているプール (該当する場合)、または使用しているプールでこのタスクを非同期的に実行します。 ForkJoinPool() にない場合は、ForkJoinPool.commonPool()。"
以上がJava 8 並列ストリームでカスタム スレッド プールを使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。