我正在为Android创建一个媒体播放器应用。我有两个线程:一个产生音频帧,另一个消耗那些帧。

我希望我的客户能够尝试使用不同大小的ArrayBlockedQueue,从“无”缓冲(确实为1)到最多10个缓冲块。

我似乎找不到Java中提供与ArrayBlockedQueue类似的功能的类,但允许我动态地使项目列表变长/变短。

问题1)是否有人知道一个类似于ArrayBlockedQueue的类,但允许我更改要容纳的项目数量吗?

然后我有一个奇怪的想法:我可以捏造吗?我可以创建一个具有新大小的新ArrayBlockedQueue,然后逐步复制旧ArrayBlockedQueue中当前存在的1-10个项目,然后将它们放入新ArrayBlockedQueue中,然后在旧项目上存储指向新ArrayBlockedQueue的指针吗?

由于不会超过10个(或我的缓冲区限制是什么),因此将项目复制到新数组中不会花费太多时间。

问题2)这是一种“合理”的方法来实现仍然给我灵活性的ArrayBlockedQueue实现吗?

问题3)是否有更好的方法来解决此问题?

-肯

最佳答案

您可能需要创建自己的BlockingQueue实现,该实现将旧队列和新队列包装在一起-从旧队列进行轮询直到其为空,然后将其设置为null以防止任何内存泄漏。这样,您不会在旧队列中丢失任何待处理的put

MyBlockingQueue {
  private MyBlockingQueue oldQueue
  private ArrayBlockingQueue newQueue

  ArrayBlockingQueue(int newCapacity, MyBlockingQueue _oldQueue) {
    oldQueue = _oldQueue
    newQueue = new ArrayBlockingQueue(newCapacity)
    E oldVal = null
    while(newQueue.remainingCapacity() > 0 &&
         (oldVal = oldPoll) != null)
      newQueue.put(oldVal)
  }

  boolean isEmpty() {
    (oldQueue == null || oldQueue.isEmpty) && newQueue.isEmpty
  }

  void put(E e) {
    newQueue.put(e)
  }

  E take() {
    E oldVal = oldPoll
    if(oldVal != null) oldVal else newQueue.take
  }

  E poll() {
    E oldVal = oldPoll
    if(oldVal != null) oldVal else newQueue.poll
  }

  private E oldPoll() {
    // If you have more than one consumer thread, then use a temporary variable
    // for oldQueue - otherwise it might be set to null between the null check
    // and the call to poll
    if(oldQueue == null) null
    else {
      E oldVal = oldQueue.poll
      if(oldVal != null) oldVal
      else {
        oldQueue = null
        null
      }
    }
  }
}

10-06 03:14