我们可以使用blockingqueue来实现循环缓冲区

时间:2011-04-12 23:24:06

标签: java

需要循环FIFO缓冲区(如果队列已满,请始终删除最早的项目),我们可以使用blockqueue实现它吗?

2 个答案:

答案 0 :(得分:1)

是。见ArrayBlockingQueue

public class ArrayBlockingQueue<E>
extends AbstractQueue<E>
implements BlockingQueue<E>, Serializable
     

由a支持的有界阻塞队列   阵列。此队列命令元素FIFO   (先入先出)。的头   queue是已经打开的元素   队列时间最长。尾巴   队列中的那个元素是   在最短的时间内排队。   在尾部插入新元素   队列和队列检索   操作获得头部元素   队列。

     

这是一个经典的“有界缓冲区”   固定大小的数组   生产者插入的元素和   消费者提取。一旦创建,   容量不能增加。   尝试将元素置于完整状态   queue将导致put操作   阻塞;尝试检索   来自空队列的元素将   同样阻止。

答案 1 :(得分:1)

这可能有所帮助:它是一个THREAD SAFE解决方案,其中ArrayBlockingQueue用作具有这些约束的循环环形缓冲区:

  1. 生产者:应该始终能够将数据放入缓冲区而不会被阻塞,即使缓冲区已满(即填充时从头部移除!)。 虽然如果我们希望生产者也被阻止,那么它就是直截了当的!

  2. 消费者:应该能够从输入中获取缓冲区,并且如果它是空的则应该被阻止(如果你也希望这是非阻塞的话,可以使用poll())。

    //模拟环形缓冲区

    BlockingQueue<Short[]> bufferQueue = new ArrayBlockingQueue<Short[]>(MAX_SIZE);
    
    Producer Code:
     ...
    //not using put() directly as it can block this thread forever
    if(!bufferQueue.offer(buffer)){
        //retrieve and remove the head of the queue to make space for this buffer
        //don't use take() as it can block this thread again if consumer took all
        //the data before call to take()!
        bufferQueue.poll();
        //now put can be used safely, remember there is only one producer!
        bufferQueue.put(buffer);
    }
    ...
    
    Consumer Code:
    ..
    //this will block till buffer is empty
    //can use .poll() if don't want blocking call
    bufferQueue.take()
    ..