请问使用AtomicInteger提供的方法和乐观锁思想对队列的push操作做保护,这样写安全吗?
/**
* 循环队列,保留一个槽位用于判断是否满了,所以实际最大容量为 SIZE - 1
*/
public static final Integer SIZE = 1001;
private AtomicInteger head = new AtomicInteger(0);
private AtomicInteger tail = new AtomicInteger(0);
private Object[] objects;
public QueueTest2() {
objects = new Object[SIZE];
}
public boolean isEmpty() {
return head.get() == tail.get();
}
public boolean isFull() {
return head.get() + 1 % SIZE == tail.get();
}
/**
* 直到成功push才会退出,否则会一直Push直到容量满了
*
* @param t
*/
public void push(T t) {
//非空并且该槽位没有被更新
if (isFull()) {
return;
}
int expectHead = head.get();
int updateHead = (head.get() + SIZE + 1) % SIZE;
if (head.compareAndSet(expectHead, updateHead)) {
objects[updateHead] = t;
} else {
push(t);
}
}
public T peek() {
return (T) objects[tail.get()];
}
public T pop() {
if (isEmpty()) {
return null;
}
int expectTail = tail.get();
int updateTail = (tail.get() + SIZE + 1) % SIZE;
T t = null;
if (tail.compareAndSet(expectTail, updateTail)) {
t = (T) objects[updateTail];
objects[updateTail] = null;
}
return t;
}
public static void main(String[] args) throws InterruptedException {
Set<Integer> set = new HashSet<>();
QueueTest2<Integer> test2 = new QueueTest2();
ExecutorService executorService = Executors.newFixedThreadPool(6);
for (int i = 0; i < 1000; i++) {
final int j = i;
executorService.execute(() -> {
test2.push(j);
});
}
executorService.awaitTermination(10, TimeUnit.SECONDS);
for (int i = 0; i < 1000; i++) {
Integer pop = test2.pop();
System.out.println(pop);
set.add(pop);
}
System.out.println(test2.head + " " + test2.tail);
System.out.println("--------------------------------------------------");
}