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.
The wait-free and lock-free circular queue is a useful technique for time and memory sensitive systems. The wait-free nature of the queue gives a fixed number of steps for each operation.
AFAIK, a lock-free circular buffer has not been invented. The problem will be dealing with the complex condition where a reader overtakes a writer or vis-versa. If you have not spent at least six months studying lock-free data structures, do not attempt to write one yourself.
The Draft CircularArray command creates an array from a selected object by placing copies along concentric circumferences. The command can optionally create a Link array, which is more efficient than a regular array.
7. Conclusions This array based lock-free queue has been proved to work in its 2 versions, the one which is thread safe in multiple producer thread configurations, and the one which is not (the one similar to [11] but allowing multiple consumer threads).
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With