プロデューサー 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()
。
この解決策が理にかなっているのかどうか教えてください。
どうもありがとう!