1

この質問のタイトルは、これが存在するかどうか疑問に思いますが、それでも:

サイズによって制限され、ブロックされないJavaのBlockingQueueが実装されているかどうかに関心がありますが、あまりにも多くの要素をキューに入れようとすると例外がスローされます。

編集-BlockingQueueをエグゼキュータに渡します。エグゼキュータはoffer()ではなくadd()メソッドを使用していると思います。別のBlockingQueueをラップし、add()への呼び出しをoffer()に委任するBlockingQueueを作成できます。

4

4 に答える 4

4

編集:あなたの新しい説明に基づいて、私はあなたが間違った質問をしていると信じています。エグゼキュータを使用している場合は、キューを変更するのではなく、カスタムのRejectedExecutionHandlerを定義する必要があります。これは、ThreadPoolExecutorを使用している場合にのみ機能しますが、使用していない場合は、キューではなくエグゼキューターを変更することをお勧めします。

オファーをオーバーライドして追加のように動作させるのは間違いだと私は思います。インターフェイスメソッドはコントラクトを構成します。ブロッキングキューを使用するクライアントコードは、ドキュメントで指定されていることを実際に実行するメソッドによって異なります。そのルールを破ると、傷ついた世界が開かれます。それ、そしてそれはエレガントではありません。


BlockingQueuesのadd()メソッドはそれを行いますが、一般的にはより良い選択である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
于 2009-08-05T05:40:29.603 に答える
0

別の BlockingQueue をラップし、add() の呼び出しを offer() に委譲する BlockingQueue を作成できます。

それが質問である場合...答えは「はい」ですが、add()をオーバーライドするサブクラスを作成することで、よりきれいに行うことができます。唯一の問題 (両方の場合) は、addオーバーライドしているメソッドにないチェック済みの例外を のバージョンがスローできないため、「ブロックする」例外をチェック解除する必要があることです。

于 2009-08-05T07:48:24.137 に答える
0

これは悲しいことです。ブロックすることはできません。ブロックしたいユースケースが非常に多いため、エグゼキュータに独自の制限付きブロック キューを提供するという考え全体には意味がありません。

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
        }
    }
于 2010-10-22T04:11:30.367 に答える
0

ソース データベースからバッチで実行されるクエリを取得し (エグゼキュータ)、バッチでエンリッチして別のデータベースに配置する (エグゼキュータ) 単純なユース ケースでは、別のデータベースに配置されるのと同じ速さでクエリを実行する必要があります。その場合、dest executor は、さらに多くのクエリを実行するためにいくつが完了したかをポーリングしてチェックし続けるよりも、問題を解決するためにブロッキング バウンド executor を受け入れる必要があります。

おっと、残りのコメントを参照してください。

于 2010-10-22T04:35:40.650 に答える