ブロックしない境界付きBlockingQueue
-
22-07-2019 - |
質問
この質問のタイトルは、これが存在するかどうかを疑いますが、それでも:
Javaの BlockingQueue 。サイズによって制限され、ブロックすることはありませんが、あまりにも多くの要素をエンキューしようとすると例外をスローします。
編集-BlockingQueueをExecutorに渡します。executeorは、offer()ではなくadd()メソッドを使用すると考えられます。別のBlockingQueueをラップし、add()の呼び出しをoffer()に委任するBlockingQueueを作成できます。
解決
編集:新しい説明に基づいて、間違った質問をしていると思われます。エグゼキューターを使用している場合、おそらくカスタム RejectedExecutionHandler 。これは、ThreadPoolExecutorを使用している場合にのみ機能しますが、そうでない場合は、キューではなく、Executorを変更することをお勧めします。
オファーをオーバーライドし、addのように動作させるのは間違いだというのが私の意見です。インターフェイスメソッドはコントラクトを構成します。ブロッキングキューを使用するクライアントコードは、ドキュメントで指定されていることを実際に実行するメソッドに依存します。その規則を破ると、傷ついた世界が開かれます。それ、そしてエレガントではない。
add () BlockingQueuesのメソッドはそれを行いますが、 offer()メソッド。通常はより良い選択です。 offer()のドキュメントから:
で指定された要素を挿入します 可能な場合、このキューの末尾 超えずにすぐにそうする キューの容量、trueを返す 成功すると、このキューの場合はfalse 一杯。通常、この方法は メソッドadd(E)よりも望ましい 次の方法でのみ要素を挿入できません 例外をスローします。
これは、特定の実装(ArrayBlockingQueue、LinkedBlockingQueueなど)に関係なく、このようなすべてのキューで機能します
BlockingQueue<String> q = new LinkedBlockingQueue<String>(2);
System.out.println(q.offer("foo")); // true
System.out.println(q.offer("bar")); // true
System.out.println(q.offer("baz")); // false
他のヒント
BlockingQueueを書くと、 別のBlockingQueueをラップし、 add()の呼び出しをoffer()に委任します。
それが質問であると想定される場合、答えは「はい」ですが、add()をオーバーライドするサブクラスを作成することで、よりきちんと行うことができます。 (両方の場合で)唯一の問題は、 add
のバージョンでは、オーバーライドするメソッドにないチェック済み例外をスローできないため、「ブロックする」ということです。例外はオフにする必要があります。
これは悲しい、ブロックできない、ブロックしたいユースケースが非常に多い、エグゼキュータに独自の制限されたブロッキングキューを提供するという考え全体は意味がありません。
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
if (runState == RUNNING && workQueue.***offer***(command)) {
if (runState != RUNNING || poolSize == 0)
ensureQueuedTaskHandled(command);
}
else if (!addIfUnderMaximumPoolSize(command))
reject(command); // is shutdown or saturated
}
}
ソースデータベースから実行されたクエリをバッチ(エグゼキューター)で取得し、バッチで強化して別のdb(エグゼキューター)に入れる簡単なユースケースでは、クエリは別のdbに入れられるのと同じ速さで実行したいでしょう。その場合、destエグゼキューターは、ブロッキングされたエグゼキューターを受け入れて、ポーリングを続け、さらにクエリを実行するために完了した数をチェックするよりも問題を解決する必要があります。
さらに、私の残りのコメントを参照してください: