web-dev-qa-db-ja.com

Java8 ForkJoinPoolとExecutors.newWorkStealingPoolの詳細な違いは?

使用中の低レベルの違いは何ですか?

ForkJoinPool = new ForkJoinPool(X);

そして

ExecutorService ex = Executors.neWorkStealingPool(X);

ここで、[〜#〜] x [〜#〜]は、並列処理の望ましいレベル、つまり実行中のスレッドです。

ドキュメントによると、私はそれらを同様に見つけました。また、通常の使用ではどちらがより適切で安全かを教えてください。私は1百万のエントリをBufferedWriterに書き込み、Unixソートを使用して第1列でソートします。

また、可能であれば保持するスレッドの数も教えてください。

注:私のシステムには8コアプロセッサと2 GB羊。

21
bit_cracker007

ワークスティーリングは、ワークキューの競合を減らすために最新のスレッドプールで使用される手法です。

従来のスレッドプールには1つのキューがあり、各スレッドプールスレッドはキューをロックし、タスクをデキューしてから、キューのロックを解除します。タスクが短く、タスクの数が多い場合、キューには多くの競合があります。ロックフリーキューを使用することは、ここでは本当に役立ちますが、問題を完全に解決するわけではありません。

最新のスレッドプールはワークスチールを使用します-各スレッドには独自のキューがあります。スレッドプールスレッドがタスクを生成するとき-それは自分のキューにエンキューします。スレッドプールスレッドがタスクをデキューしたい場合-最初に自分のキューからタスクをデキューしようとし、それがない場合は他のスレッドキューから作業を「スチール」します。これは実際にtheradpoolの競合を減らし、パフォーマンスを改善します。

newWorkStealingPoolは、スレッド数をプロセッサ数として、ワークステアリングを利用するスレッドプールを作成します。

newWorkStealingPoolには新しい問題があります。 4つの論理コアがある場合、プールには合計4つのスレッドがあります。私のタスクがブロックする場合-たとえば、同期IO-CPUを十分に活用していません。必要なのは、4つのactiveでのスレッドany givenモーメント、たとえば-AESを暗号化する4つのスレッドとIOが完了するのを待つ別の140のスレッド。

これがForkJoinPoolが提供するものです。タスクが新しいタスクを生成し、そのタスクが完了するまで待機する場合、プールはCPUを飽和させるために新しいアクティブスレッドを挿入します。 ForkJoinPoolも仕事を盗むことを利用していることに言及する価値があります。

どちらを使用しますか? fork-joinモデルを使用している場合、またはタスクが無期限にブロックされていることがわかっている場合は、ForkJoinPoolを使用してください。タスクが短く、ほとんどがCPUに依存している場合は、newWorkStealingPoolを使用します。

そして、何も言われていないが、最近のアプリケーションは、利用可能なプロセッサの数でスレッドプールを使用し、ブロッキングを防ぐためにasynchronous IOおよびlock-free-containersを利用する傾向がある。これは(通常)最高のパフォーマンスを提供します。

23
David Haim

これは、Fork/Joinフレームワークの抽象化にすぎません...

/**
* Creates a work-stealing thread pool using all
* {@link Runtime#availableProcessors available processors}
* as its target parallelism level.
* @return the newly created thread pool
* @see #newWorkStealingPool(int)
* @since 1.8
*/
public static ExecutorService newWorkStealingPool() {
    return new ForkJoinPool(Runtime.getRuntime().availableProcessors(),
                            ForkJoinPool.defaultForkJoinWorkerThreadFactory,
                            null, true);
}
2
Rafael Bernabeu