Search code examples
javalock-freecircular-buffer

Lock Free Circular Array


I am thinking about implementing a lock free circular array. One problem is maintaining the head and tail pointers in a lock free manner. The code I have in mind is:

int circularIncrementAndGet(AtomicInteger i) {
    i.compareAndSet(array.length - 1, -1);
    return i.incrementAndGet();
}

Then I would do something like:

void add(double value) {
    int idx = circularIncrementAndGet(tail);
    array[idx] = value;
}

(Note that if the array is full old values will be overwritten, I am fine with that).

Does anyone sees a problem with this design? I suspect there might be a race condition I am not seeing.


Solution

  • A simpler approach is to use a power of 2 size and do the following.

     final double[] array;
     final int sizeMask;
     final AtomicInteger i = new AtomicInteger();
    
     public CircularBuffer(int size) {
          assert size > 1 && ((size & (size -1)) == 0); // test power of 2.
          array = new double[size];
          sizeMask = size -1;
     }
    
     void add(double value) {
         array[i.getAndIncrement() & sizeMask] = value;
     }