将绑定添加到无界队列

时间:2015-12-22 11:20:15

标签: java multithreading data-structures concurrency lock-free

我有一个用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的精确边界一样;但是,如果我能证明这个不变量,那么我就不需要问如何证明这个不变量。

1 个答案:

答案 0 :(得分:3)

难道你不能以原样的方式使用if (size.incrementAndGet() < max) {吗?

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

这肯定会强制你的不变量。