阻塞queue系列之LinkedBlockingQueue

来源:互联网 发布:深度睡眠知乎 编辑:程序博客网 时间:2024/05/22 13:52

LinkedBlockingQueue继承AbstractQueue,实现了BlockingQueue,Serializable接口。内部使用单向链表存储数据。可定义容量,默认初始化容量是Integer最大值(可能出现内存溢出)。插入和取出使用不同的锁,putLock插入锁,takeLock取出锁,添加和删除数据的时候可以并行。多CPU情况下可以同一时刻既消费又生产。LinkedBlockingQueue在大多数并发的场景下吞吐量比ArrayBlockingQueue,但是性能不稳定。

    private final ReentrantLock takeLock = new ReentrantLock();    /** Wait queue for waiting takes */    private final Condition notEmpty = takeLock.newCondition();    /** Lock held by put, offer, etc */    private final ReentrantLock putLock = new ReentrantLock();    /** Wait queue for waiting puts */    private final Condition notFull = putLock.newCondition();

构造函数

public LinkedBlockingQueue() {        this(Integer.MAX_VALUE);    }
public LinkedBlockingQueue(int capacity) {        if (capacity <= 0) throw new IllegalArgumentException();        this.capacity = capacity;        last = head = new Node<E>(null);    }
 public LinkedBlockingQueue(Collection<? extends E> c) {        this(Integer.MAX_VALUE);        final ReentrantLock putLock = this.putLock;        putLock.lock(); // Never contended, but necessary for visibility        try {            int n = 0;            for (E e : c) {                if (e == null)                    throw new NullPointerException();                if (n == capacity)                    throw new IllegalStateException("Queue full");                enqueue(new Node<E>(e));                ++n;            }            count.set(n);        } finally {            putLock.unlock();        }    }

常用方法

常用方法与ArrayBlockingQueue类似,方法具体实现可以参考源码。ArrayBlockingQueue