0

短いバージョン - 2 つのキューを 1 つにラップしてスレッド プールで使用する最も効率的な方法を探しています。スレッド プールでは、空でない限りキューの 1 つの内容が優先され、その後、キューにフォールバックします。 2番目のキュー。

詳細バージョン: システム内の複数のスレッド プール。それぞれに独自のキューがあります。

「外部」リクエストは外部から送信され、プールの 1 つに送信され、そこでしばらく処理された後、別のキューに転送されます。最初の転送後、リクエストは完了するまで「内部」と見なされます。リクエストはすべてのスレッド プール間で転送され、開始されたスレッド プールに到達する可能性があります。

私がやりたいことは、各スレッドプールのキューに内部リクエストが含まれている場合、キューが内部リクエストを使い果たすまで最初に処理され、次に外部リクエストに切り替わることです。新しい内部が表示された場合は、次に処理する必要があります。

純粋な FIFO は必要ありません。現在、スレッド プールごとに 1 つの LinkedTransferQueue を使用しています。これは、多くのコンシューマーと多くのプロデューサーに関して私が見つけた最速の種類の FIFO キューであるためです。挿入率が非常に高く、LinkedTransferQueue のスピンロックは驚くほどうまく機能します。

キューのサイズは (拒否と同様に) 別の場所で処理されるため、適切な put/take 動作のみが必要です。

うまくいかなかった解決策の過去の試み:

  1. PriorityBlockingQueue - 遅すぎます。特に私のハードウェアでは、何らかの理由でロックがうまくいきません。(2.4 GHz クアッド コア ラップトップは、2x 2.0 GHz ヘキサ コア サーバーよりもほぼ優れています)
  2. 2 つの LinkedBlockingQueue を手動でラップする - 正常に動作しましたが、遅すぎました。ONE LinkedBlockingQueue を使用するのも遅すぎます。
  3. 2 つの ArrayBlockingQueue を手動でラップ - LinkedBlockingQueue と同じ。

解決策についての考え:

  • 2 つの LinkedTransferQueues を手動で「マージ」しています...しかし、そのコードを見た後、私は何かを壊さずにそれを行うのに十分賢くないのではないかと心配しています。
  • しばらくスピンし、何かが見つかるまで両方のキューで peek() を実行します...これは基本的にスピンロックであり、しばらくこれを実行できると思いますが、LinkedTransferQueue と同じ動作が必要だと思います。あれは。しばらくスピンしてから、しばらく降伏またはスリープします。しかし、私は目を覚ます方法がありません。(編集:「本当の」ロックを避けることができれば本当に好きです)

外部で peek() を実行し、代わりに内部で if null ブロッ​​クを実行することはできません。これは、何かが外部に挿入される可能性があり、内部で待機してブロックされるためです。外部から処理しない限り、物事は内部で終わることができないため、内部からブロックを解除することはありません... 180度回転させても同じです(システム内から来ることを除いて)

意味不明な投稿ですみません…

4

1 に答える 1