private final int capacity;
/** 原子变量,记录元素个数 */
private final AtomicInteger count = new AtomicInteger();
/**
*/
transient Node head;
/**
*/
private transient Node last;
/** 用来控制同时只有一个线程可以从队头获取元素 */
private final ReentrantLock takeLock = new ReentrantLock();
/** 条件队列,队列为空时,执行出队take操作的线程将会被置入该条件队列 */
private final Condition notEmpty = takeLock.newCondition();
/** 用来控制同时只有一个线程可以从队尾插入元素 */
private final ReentrantLock putLock = new ReentrantLock();
/** 条件队列,队列满时,执行入队操作put的线程将会被置入该条件队列 */
private final Condition notFull = putLock.newCondition();
}
单向链表实现,维护head和last两个Node节点,head是哨兵节点,head.next是第一个真正的元素,last指向队尾节点。
队列中的元素通过AtomicInteger类型的原子变量count记录。
维护两把锁:takeLock保证同时只有一个线程可以从对头获取元素,putLock保证只有一个线程可以在队尾插入元素。
维护两个条件变量:notEmpty和notFull,维护条件队列,用以存放入队出队阻塞的线程。
如果希望获取一个元素,需要先获取takeLock锁,且notEmpty条件成立。 如果希望插入一个元素,需要先获取putLock锁,且notFull条件成立。
构造器
===
使用LinkedBlockingQueue的时候,可以指定容量,也可以使用默认的Integer.MAX_VALUE,几乎就是无界的了,当然,也可以传入集合对象,直接构造。
// 如果不指定容量,默认容量为Integer.MAX_VALUE (1 << 30) - 1
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
// 传入指定的容量
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
// 初始化last 和 head指针
last = head = new Node(null);
}
// 传入指定集合对象,容量视为Integer.MAX_VALUE,直接构造queue
public LinkedBlockingQueue(Collection extends E> c) {
this(Integer.MAX_VALUE);