无锁数组队列
2020-06-02 本文已影响0人
万福来
无锁数组队列
static class FreeLockArrayQueue<E> {
private AtomicReferenceArray<E> queue;
private AtomicInteger putIndex;
private AtomicInteger takeIndex;
private int size;
FreeLockArrayQueue(int size) {
this.size = size;
queue = new AtomicReferenceArray<E>(size);
putIndex = new AtomicInteger(0);
takeIndex = new AtomicInteger(0);
}
public void put(E e) {
for (; ; ) {
int curr = putIndex.get();
if (queue.compareAndSet(curr % size, null, e)) {
putIndex.incrementAndGet();
break;
}
if (putIndex.get() < takeIndex.get() + size) {
putIndex.incrementAndGet();
}else{
LockSupport.parkNanos(this, 3000L);
}
}
}
public E take() {
for (; ; ) {
int curr = takeIndex.get();
if (curr <= putIndex.get()) {
E expect = queue.get(curr % size);
if (expect != null && queue.compareAndSet(curr % size, expect, null)) {
takeIndex.incrementAndGet();
return expect;
}
}
Thread.currentThread().yield();
if (takeIndex.get() < putIndex.get()) {
takeIndex.incrementAndGet();
}else{
LockSupport.parkNanos(this, 3000L);
}
}
}
}