我有一个用Java编写的近似并发有界队列 - 它旨在模仿LinkedBlockingQueue的行为,除了a。它不使用锁和b。它只部分尊重队列的大小不变量。
public class LockFreeBoundedQueue<T> {
private final ConcurrentLinkedQueue<T> queue = new ConcurrentLinkedQueue<>();
private final AtomicInteger size = new AtomicInteger(0);
private final int max;
public LockFreeBoundedQueue(int max) {
this.max = max;
}
public T poll() {
T t = queue.poll();
if(t != null) {
size.decrementAndGet();
}
return t;
}
public boolean offer(T t) {
if(t == null) throw new NullPointerException();
if(size.get() < max) {
size.incrementAndGet();
return queue.offer(t);
}
return false;
}
public int size() {
return queue.size();
}
}
如果队列使用锁来强制执行大小不变量,那么模型检查将相对简单,因为队列只有三种状态:空(poll
返回null),完整(offer
返回是的,既不空也不满。但是,在size.get() < max
size == (max - 1)
期间,有多个线程可以通过size > max
保护,这将使队列处于N
状态。我不熟悉如何指定或验证这种“近似不变量”。
直观地,给定一个可以同时调用offer
的{{1}}个线程的系统,我可以对队列进行建模,就像它具有max + N
的精确边界一样;但是,如果我能证明这个不变量,那么我就不需要问如何证明这个不变量。
答案 0 :(得分:3)
难道你不能以原样的方式使用if (size.incrementAndGet() < max) {
吗?
if (size.incrementAndGet() < max) {
return queue.offer(t);
} else {
// Undo my excessive increment.
size.decrementAndGet();
}
这肯定会强制你的不变量。