8

プロデューサー P が 1 人、コンシューマー C1 と C2 が 2 人いるとします。また、Q1 と Q2 の 2 つのキューがあり、どちらも特定の容量があります。

P はアイテムを生成し、Q1 と Q2 に交互に入れます。アイテムは特定の消費者向けに生産され、他の消費者が消費することはできません。Java で以下を実装するにはどうすればよいですか: 3 つのスレッドを開始した後、Q1 が空の場合、スレッド C1 は、Q1 に何かがあるときに通知されるまでブロックされます。Q2も同様です。また、Q1 と Q2 の両方が満杯になると、Q1 または Q2 のいずれかが満杯でないことが通知されるまで、P はブロックされます。

キューが空のときにコンシューマーをブロックする BlockingQueue を使用することを考えていました。しかし問題は、どちらかのキューがいっぱいになると、プロデューサーがブロックされることです。この問題を解決するために使用できる Java のデータ構造はありますか?

アップデート

私は自分で解決策を持っていますが、それが効率的かどうかはわかりません。まだ 2 つの BlockingQueues を持つことができます。また、消費者がキューからアイテムを取得するときは を使用するBlockingQueue.take()ため、キューにアイテムがない場合はブロックされます。プロデューサーがアイテムをいずれかのキューに追加するとき、それは を使用しますBlockingQueue.offer()。この操作によってブロックされることはなく、キューがいっぱいの場合は「false」になります。さらに、いっぱいになっていないキューの数を示すために AtomicInteger を保持します。プロデューサー P がアイテムをキューに入れようとするたびに、false が返された場合、AtomicInteger を 1 減らします。0 になると、プロデューサーは を呼び出しますAtomicInteger.wait()。コンシューマーがキューから項目を取得するたびに、AtomicInteger も調べます。0 の場合、消費者はそれを 1 増やして を呼び出しますAtomicInteger.notify()

この解決策が理にかなっているのかどうか教えてください。

どうもありがとう!

4

3 に答える 3

1

Striped Executor Serviceを検討しましたか。これにより、問題を解決し、消費者をより効率的なプールに入れることができます。

于 2013-05-31T14:29:13.400 に答える
0

どのデータ構造/メッセージ サーバーを選択しても、これらのいずれかでリソースが不足する可能性があります。メモリまたはディスク容量には常に制限があります。

だから実は生産者が止められるのは悪くない。

キューがいっぱいになっている場合は、バランスの復元を試みる必要があります。コンシューマーを追加できます。コンシューマーのパフォーマンスを向上させることができます。これが不可能な場合は、何かが実際にプロデューサーを抑制する必要があります。これは、メモリ不足エラーdevice に空き領域がないことを回避する方法です。

最後に、とにかくキューを監視するのはデータセンターの義務です。キューの充填度​​が限界に達した場合 (たとえば > 80%)、通知する必要があります。

アップデート

キューの 1 つがいっぱいであるために、プロデューサーがすべてのキューで送信できない場合、バッファリングするかどうかはプロデューサー次第ですが、バッファリングはキューが行うべきことです。

于 2013-05-31T14:42:20.760 に答える