这个问题的标题让我怀疑这是否存在,但仍然:

我感兴趣的是是否有Java的实现 阻塞队列, ,它受大小限制,并且永远不会阻塞,而是在尝试将太多元素排入队列时抛出异常。

编辑 - 我将 BlockingQueue 传递给 Executor,我认为它使用其 add() 方法,而不是 Offer()。可以编写一个 BlockingQueue 来包装另一个 BlockingQueue 并将对 add() 的调用委托给 Offer()。

有帮助吗?

解决方案

编辑: 根据您的新描述,我认为您问错了问题。如果您使用执行器,您可能应该定义一个自定义 拒绝执行处理程序 而不是修改队列。这仅在您使用 ThreadPoolExecutor 时才有效,但如果您不使用 ThreadPoolExecutor,则修改 Executor 而不是队列可能是更好的主意。

我认为覆盖 Offer 并使其表现得像 add 是错误的。接口方法构成了一个契约。使用阻塞队列的客户端代码取决于实际执行文档指定操作的方法。打破这条规则就会带来一个充满伤害的世界。那,而且很不优雅。


添加() BlockingQueues 上的方法可以做到这一点,但它们还有一个 提供() 方法通常是更好的选择。来自 Offer() 的文档:

如果可以立即执行此操作而不超过队列的能力,则将指定的元素插入该队列的尾部,在成功后返回,如果该队列已满,则误差。通常,此方法比方法添加(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的版本不能抛出任何检查不在你覆盖方法的异常,所以你的“将块”例外将需要选中。

这是可悲的,你不能阻止,有这么多的使用情况下,你想阻止,提供自己的界阻塞队列执行人的整体思路是没有意义的。

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
        }
    }

有一个简单的例子来获得批量(执行者)从源数据库执行查询,丰富了批量投入另一个数据库(执行),你会只想尽可能快地被投入到另一个数据库执行查询。在这种情况下,执行程序DEST应该接受阻挡界执行来解决这个问题比保持轮询和检查多少已经完成执行多个查询。

哎呀,多看我剩下评论:

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top