/ / JAVA-並行性-マルチプロデューサー/マルチコンシューマーのリクエストおよびレスポンスキュー-Java、マルチスレッド、並行性

JAVA - 同時実行性 - マルチプロデューサ/マルチコンシューマのリクエストとレスポンスキュー - Java、マルチスレッド、同時実行性

3種類のスレッドがあります。メインスレッド、ワーカー、クライアント。 また、要求と応答のキューの2つのキューがあります。

メインスレッドは多くのクライアントを生成します。 各クライアントは何かを要求し、メインの要求キューに追加する必要があります。メインは適切なワーカーを生成し、ワーカーは要求を処理します。完了すると、[結果、呼び出しスレッド#]を応答キューに追加します。各クライアントは、リクエストの後、レスポンスを待機します。

一致するリンクキューを使用する必要があると考えているキュー用。これでいいですか? クライアントは、スレッドIDとポーリングを見つけるまで覗く必要がありますか?頭がピークとポーリングの間で変わる可能性があるという仮説はありますか?多くの競合と遅延があるので、ロックを追加したくありません。

これは、スレッドセーフかつ並行である必要があり、デッドロックや飢starがないようにする必要があります。

回答:

回答№1は0

私は単一のリクエストキューを持ち、その後クライアントごとに個別の応答キュー。ワーカーに送信されるリクエストの一部として、クライアントの応答キューへの参照を配置して、クライアントが継続的に行う必要がないようにします peak() 単一の応答キューを介して。

つかいます BlockingQueues 要求と応答の両方のキュー。 リクエストキューの容量を増やして(つまり、クライアントスレッドの数よりも多く)飢starを排除します。応答キューの容量は1つだけです。つかいます put() そして take() の代わりに peak() そして poll().

これがシーケンスです:

  1. クライアントがリクエストを作成します。

  2. クライアントはそれを要求キューに入れ、キューがいっぱいになるとブロックします。 (これが、要求キューの容量を大きくする理由です。)

  3. クライアントコール take() それは空ですので、独自の応答キューとブロックです。

  4. ワーカースレッドが生成されるか、空の要求キューで既に生成されブロックされています。

  5. ワーカースレッドは、アイテムを要求キューから削除して処理します。完了すると、クライアントの応答キューに配置されます(要求で渡された応答キューへの参照を使用します)。

  6. これにより、クライアントのブロックが解除されます。クライアントは、応答を応答キューから削除して処理します。