【问题标题】:Get the capacity of an ArrayBlockingQueue获取 ArrayBlockingQueue 的容量
【发布时间】:2020-08-08 22:23:35
【问题描述】:

我需要将 ArrayBlockingQueue 容量缩小 1。

我在想没有什么比这更容易了:

  1. 获取当前队列的容量。
  2. 使用capacity - 1 创建一个新队列
  3. 使用BlockingQueue.drainTo 函数将旧队列中的任何元素移至新队列。
  4. 请假一天...

但是,我在第 1 步完全被窃听了。由于某些不可思议的原因,ArrayBlockingQueue 没有公开容量。我想不出这是私有的原因,它是一个有界队列并提供getRemainingCapacity方法,为什么我不能获得容量?

我不能size() + getRemainingCapacity(),因为这是一个并发队列,总是有可能在 size 和 getRemainingCapacity 调用之间更改队列。

当然,我不是第一个需要 ArrayBlockingQueue 容量的人。没有扩展整个类来添加getCapacity 方法,或者创建一个单独的结构来映射我的队列的容量,有没有简单的解决方案?

或者也许是不应该知道容量的明智原因? (除了疏忽)

更多背景: 我的多线程程序使用了许多队列,它调用BlockingQueue.getRemainingCapacity 函数来了解队列何时已满,然后从那里处理它。在一个罕见的极端情况下,程序在填充它的过程中发现队列容量太大了 1 个元素。我需要将队列的大小减少 1,否则它永远不会填满,也永远不会得到处理。

【问题讨论】:

  • 您是否尝试过自己跟踪容量,ArrayBlockingQueue 接受构造函数中的容量参数,这将是一个丑陋的解决方案,但希望它可以工作?
  • @DusanMalusev 是的,我试图避免这种情况,因为我有数百个这样的队列......现在我正在扩展这个类,不过这个简单的用法似乎真的很迟钝。跨度>
  • 我同意你的观点,它真的转储不暴露容量,在数组队列中容量总是保持不变,它应该是恒定时间操作,而不是像多线程系统中难以获得的长度,毕竟你使用的是数组队列而不是链表,容量永远不会改变。也许他们想要跨所有队列的统一 API,而不是添加像 getCapacity 这样的方法,因为在所有队列类上实现恒定时间操作会很棘手。
  • 你可能是对的,我想可以省略它以创建队列之间的一致性。
  • 这对我来说是唯一合乎逻辑的解决方案。也许JDK开发人员知道而我们不知道的其他东西

标签: java queue


【解决方案1】:

现在,我要这样做......

import java.util.concurrent.ArrayBlockingQueue;

@SuppressWarnings("serial")
public class InformativeBlockingQueue<E> extends ArrayBlockingQueue<E>
{
    private final int visibleCapacity;
    
    public InformativeBlockingQueue(int capacity)
    {
        super(capacity, false);
        this.capacity = capacity;
    }

    public InformativeBlockingQueue(int capacity, boolean fair)
    {
        super(capacity, fair);
        this.visibleCapacity = capacity;
    }
    
    public int getCapacity()
    {
        return visibleCapacity;
    }
}

我觉得它不应该只是为了获得容量而需要扩展。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-08
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    相关资源
    最近更新 更多