0

Needs a circular FIFO buffer (Always remove the ealiest item if the queue is full), can we implement it using blockingqueue?

user496949
  • 83,087
  • 147
  • 309
  • 426

2 Answers2

1

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

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.

Jason S
  • 184,598
  • 164
  • 608
  • 970
  • 1
    My quetsion is that when the queue is full, can put method removing the head and insert into the tail automatically? – user496949 Apr 12 '11 at 23:38
  • Automatically: no. But you could use `offer()`, and if it fails, remove the head yourself and try again. – Jason S Apr 13 '11 at 00:05