将绑定添加到无界队列

Adding a bound to an unbounded queue

我有一个用 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 returns null),满( offer returns false),既不空也不满。但是,有可能有多个线程在 size == (max - 1) 时通过 size.get() < max 守卫,这将使队列处于 size > max 状态。我不熟悉如何指定或验证这种 "approximate invariant"。

直觉上,给定一个具有 N 个线程并可以同时调用 offer 的系统,我可以对队列进行建模,就好像它具有 max + N 的精确界限;但是,如果我能证明这个不变量成立,那么我就不需要问如何证明这个不变量成立了。

您不能以原定的原子方式使用 if (size.incrementAndGet() < max) { 吗?

        if (size.incrementAndGet() < max) {
            return queue.offer(t);
        } else {
            // Undo my excessive increment.
            size.decrementAndGet();
        }

当然这会强制执行您的不变性。