shz.core.queue.a.ConcurrentArrayQueue Maven / Gradle / Ivy
package shz.core.queue.a;
import shz.core.lock.ReadWriteLockHolder;
import java.io.Serializable;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
/**
* 基于循环动态数组的队列
*/
public abstract class ConcurrentArrayQueue extends ReadWriteLockHolder implements RandomAccess, Serializable {
private static final long serialVersionUID = 8816397923504057202L;
protected static final int DEFAULT_CAPACITY = 8;
protected int capacity, size, tail, head;
ConcurrentArrayQueue(int capacity) {
if (capacity < 1) throw new IllegalArgumentException();
this.capacity = capacity + 1;
}
public final int size() {
readLock.lock();
try {
return size;
} finally {
readLock.unlock();
}
}
public final boolean isEmpty() {
readLock.lock();
try {
return size == 0;
} finally {
readLock.unlock();
}
}
public final void clear() {
writeLock.lock();
try {
tail = head = 0;
size = 0;
} finally {
writeLock.unlock();
}
}
protected final void checkEmpty() {
if (size == 0) throw new NoSuchElementException();
}
protected final void beforeOffer() {
if (size == capacity - 1) {
if (capacity == Integer.MAX_VALUE) throw new OutOfMemoryError();
int newCap = capacity >= 64 ? capacity + (capacity >> 1) : capacity << 1;
resize(newCap < 0 ? Integer.MAX_VALUE : newCap);
}
}
protected abstract void resize(int capacity);
protected final void afterOffer() {
tail = (tail + 1) % capacity;
++size;
}
protected final void afterPoll() {
setNull(head);
head = (head + 1) % capacity;
--size;
reduce();
}
private void reduce() {
if (capacity > 64) {
int newCap = size + 1 + (size + 1 >> 1);
if (newCap + (newCap >> 1) <= capacity) resize(newCap);
} else if (size + 1 <= capacity >>> 2) resize(capacity >> 1);
}
protected abstract void setNull(int i);
public final void removeTail() {
writeLock.lock();
try {
if (size == 0) return;
if (tail == 0) tail = capacity - 1;
else --tail;
setNull(tail);
--size;
reduce();
} finally {
writeLock.unlock();
}
}
}