2012-04-14 27 views
6

私のプロジェクトでは、クライアントから作業要求を受け取るJava実行フレームワークを構築しています。作業(さまざまなサイズ)は一連のタスクに分割され、処理のためにキューに入れられます。各タイプのタスクを処理するキューが別々にあり、各キューはThreadPoolに関連付けられています。 ThreadPoolsは、エンジンの全体的なパフォーマンスが最適になるように設定されています。仕事/仕事Stealing ThreadPoolExecutor

この設計は、要求を効果的に負荷分散するのに役立ち、大きな要求がシステムリソースを大量に消費することにはなりません。ただし、キューの一部が空で、それぞれのスレッドプールがアイドル状態になっていると、ソリューションが無効になることがあります。

これをさらにうまくするために、負荷の高いキューが他のThreadPoolsから助けを得ることができるように、作業/タスクのスティッキング技術を実装することを考えていました。しかし、これはJavaが複数のキューをThreadPoolに関連付けることを許さず、仕事盗みの概念をサポートしないので、私自身のExecutorを実装する必要があります。

Fork/Joinについて読むが、私のニーズに合っていないようだ。このソリューションを構築するための提案や代替方法は非常に役に立ちます。

おかげ アンディ

+1

すべてのCPUを忙しくする方法について考える必要があります。 CPUを最大限に活用している場合、スレッドの一部がアイドル状態であるかどうかは関係ありません。 –

+0

スレッドプールにcpusを持つスレッドと同じ数のスレッドがある場合、他のすべてのスレッドプールがアイドル状態であっても、個々のスレッドプールはすべてのCPUを「盗む」ことができます。 –

+0

@PeterLawrey - それは本当ですが、プールがたくさんある場合、すべてのプールのすべてのスレッドが同時に動作しているとパフォーマンスが低下する可能性があります。 – jtahlborn

答えて

1

あなたは「プライマリ」キューと0以上の二次キューに裏打ちされたカスタムBlockingQueueの実装を(私はあなたが主にoffer()take()メソッドを実装する必要があると思う)実装することができます。 takeは常に空でない場合はプライマリバッキングキューから、それ以外の場合はセカンダリキューからプルできます。

実際、すべての作業者がすべてのキューにアクセスできるが、特定のキューを優先するプールがある方がよい場合があります。あなたは、異なる労働者に異なる優先順位を割り当てることによって、最適な仕事率を思いつくことができます。完全にロードされたシステムでは、作業者は最適な比率で作業する必要があります。負荷の低いシステムでは、作業者は他のキューを手助けすることができます。

+0

これは良いアイデアのように思えますが、私はPOCを試してみることにしています。 –

2

ForkJoinPoolとお考えですか? fork-joinフレームワークは素敵なモジュラー形式で実装されていますので、あなたは単にワークスティールスレッドプールを使うことができます。

+1

APIを読んでも、通常のThreadPoolExecutorとの違いを理解できません。おそらくそこではより細かい側面が欠けているでしょう。 –

+0

はい、あなたが持っているのは、実際には柔軟にしたいパーティション化スキームです。パーティションの境界が作業負荷に応じて移動するようにします。 「仕事の窃盗」は、細かいタスクの細分化を含むスキームのより専門用語であるかもしれません。あるスレッドで実行されるタスクは、サブタスクを生成し、それを自身の両端キューにプッシュして、他のスレッドがその作業を盗むことができます。だから、もしあなたが "スレッドプールパーティショニング"という言葉で研究するのであれば、あなたの場合に適したものを見つけるでしょう。 –

2

Java 8には、Executorsクラスのためのファクトリとユーティリティメソッドがあります。 私はあなたが望むものであると信じている、仕事を盗むスレッドプール(here)の実装があります。

+0

これは、グローバルプールからこれらのスレッドを借用するのではなく、新しいForkJoinThreadsを必要に応じて作成するという欠点のみです。クライアントが渡すことができる共通プールまたはプールである可能性があります。 –