我正在为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
}
}
}
}