LinkedBlockingQueue
Attributes
- capacity:队列容量,可通过构造方法传入,否则为Integer.MAX_VALUE
- count:当前元素数目,AtomicInteger类型
- head:队列头,特征:head.item == null
- last:队列尾,特征:last.next == null
- takeLock:取操作的锁(ReentrantLock)
- notEmpty:取操作锁拿到的condition
- putLock:存放操作的锁(ReentrantLock)
- notFull:存放操作锁拿到的condition
Construction Method
- LinkedBlockingQueue():初始化默认队列容量为Integer.MAX_VALUE的LinkedBlockingQueue
- LinkedBlockingQueue(capacity):初始化指定队列容量的LinkedBlockingQueue,并且设定head和last为item值为null的node
Method
put()
特征:往队列put值时,如果队列满了就一直等待
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
int c = -1;
Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
/*
* 如果队列满了,就等待,直到队列有空闲才会被唤醒
*/
while (count.get() == capacity) {
notFull.await();
}
// 放入队尾
enqueue(node);
// 计数原子的加1
c = count.getAndIncrement();
// 加完之后如果队列有空闲,就唤醒等待往队列放值的线程
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
// 表示此次put值之前队列是空的,现在队列有值了,就去唤醒取值的线程
if (c == 0)
signalNotEmpty();
}
offer(timeout)
特征:往队列put值时,如果队列满了就等待timeout时间长度,如果还满就直接返回false
public boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException {
if (e == null) throw new NullPointerException();
long nanos = unit.toNanos(timeout);
int c = -1;
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
// 队列满了的情况下,等待timeout的时间,如果超过这个时间就返回false
while (count.get() == capacity) {
if (nanos <= 0)
return false;
nanos = notFull.awaitNanos(nanos);
}
enqueue(new Node<E>(e));
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
// 表示此次offer值之前队列是空的,现在队列有值了,就去唤醒取值的线程
if (c == 0)
signalNotEmpty();
return true;
}
offer()
特征:往队列put值时,如果队列满了就直接返回false
public boolean offer(E e) {
if (e == null) throw new NullPointerException();
final AtomicInteger count = this.count;
// 如果队列满了,立即返回false
if (count.get() == capacity)
return false;
int c = -1;
Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
if (count.get() < capacity) {
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
}
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
// 返回是否offer成功
return c >= 0;
}
take()
public E take() throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
// 如果队列空了,等待直到被唤醒
while (count.get() == 0) {
notEmpty.await();
}
// 取出head.next的item值
x = dequeue();
// 技术值原子的减一
c = count.getAndDecrement();
// take完后如果队列不为空,则唤醒等待take的队列
if (c > 1)
notEmpty.signal();
} finally {
takeLock.unlock();
}
// 如果take之前队列是满的,则take完后唤醒往队列放值的线程
if (c == capacity)
signalNotFull();
return x;
}
poll(timeout)
public E poll(long timeout, TimeUnit unit) throws InterruptedException {
E x = null;
int c = -1;
long nanos = unit.toNanos(timeout);
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
// 队列空的时候等待timeout时间后返回值
while (count.get() == 0) {
if (nanos <= 0)
return null;
nanos = notEmpty.awaitNanos(nanos);
}
x = dequeue();
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal();
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();
return x;
poll()
public E poll() {
final AtomicInteger count = this.count;
// 队列空的时候立即返回null
if (count.get() == 0)
return null;
E x = null;
int c = -1;
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
if (count.get() > 0) {
x = dequeue();
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal();
}
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();
return x;
}
Inner Class
Node
-
item:value值 next: 下一个node