开发者

Can we use blockingqueue to implement circular buffer

开发者 https://www.devze.com 2023-02-24 11:08 出处:网络
Needs a circular FIFO buffer (Always remove the ealies开发者_开发知识库t item if the queue is full), can we implement it using blockingqueue?Yes. See ArrayBlockingQueue:

Needs a circular FIFO buffer (Always remove the ealies开发者_开发知识库t item if the queue is full), can we implement it using blockingqueue?


Yes. See ArrayBlockingQueue:

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

A bounded blocking queue backed by an array. This queue orders elements FIFO (first-in-first-out). The head of the queue is that element that has been on the queue the longest time. The tail of the queue is that element that has been on the queue the shortest time. New elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue.

This is a classic "bounded buffer", in which a fixed-sized array holds elements inserted by producers and extracted by consumers. Once created, the capacity cannot be increased. Attempts to put an element to a full queue will result in the put operation blocking; attempts to retrieve an element from an empty queue will similarly block.


This might help: it's a THREAD SAFE solution where ArrayBlockingQueue used as a circular ring buffer with these constraints:

  1. Producer: should always be able to put data in the buffer without getting blocked even if buffer is full (that is remove from head when full!). Though if we want producer to get also blocked then its straightforward!

  2. Consumer: should be able to take buffer from input and should get blocked if its empty (can use poll() if you also want this to be non blocking).

    //simulating ring buffer

    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()
    ..
    
0

精彩评论

暂无评论...
验证码 换一张
取 消