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



需要一个循环FIFO缓冲区(如果队列已满,总是删除最实际的项目),我们可以使用blockingqueue实现它吗?

是。看到ArrayBlockingQueue:

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

有界阻塞队列,由数组中。这个队列对元素进行FIFO排序(先进先出)。的头。Queue是已经打开的元素排队的时间最长。尾巴的元素排队的时间最短。在尾部插入新元素的队列,以及队列检索操作获取头部的元素

这是一个经典的"有界缓冲区",在固定大小的数组中保存的是什么由生产者和插入的元素由消费者提取。一旦创建,不能增加容量。试图将一个元素放满队列将导致放置操作阻塞;试图检索元素将从空队列中取出同样块。

这可能会有所帮助:这是一个线程安全的解决方案,其中ArrayBlockingQueue用作具有这些约束的环形缓冲区:

  1. Producer:应该始终能够将数据放入缓冲区而不会被阻塞,即使缓冲区已满(即当缓冲区满时从head中删除!)如果我们想让制作人也被封锁,那就很简单了!

  2. Consumer:应该能够从输入中获取缓冲区,如果缓冲区为空,应该被阻塞(如果你也希望这是非阻塞的,可以使用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()
    ..
    

最新更新