文章目录

ArrayBlockingQueue
1、定义
package java.util.concurrent;
public class ArrayBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
2、简介
ArrayBlockingQueue 是一个基于数组的阻塞队列,创建时必须要指定数组的长度。
既然它在 J.U.C 包内,说明是支持并发线程安全的,内部使用 ReenTrantLock 来保证线程安全。
3、常用方法
offer、put 入队。
poll、take 出队。
offer 和 poll 非阻塞方法。
put 和 take 阻塞方法。
peek() 获取第一个入队的元素。
remove() 移除指定的元素。
3.1、入队方法
内部放入队列:
private void enqueue(E x);
add 方法,最终调用的是 offer 方法。
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
offer 方法,非阻塞方法,队列满时返回 false,否则调用 enqueue 放入队列,并返回 true。
public boolean offer(E e) {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}
put 方法,阻塞方法,队列满时,会一直等待,直到被其他线程唤醒,唤醒后调用 enqueue 放入队列。
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
enqueue(e);
} finally {
lock.unlock();
}
}
3.2、出队方法
内部出队列:
private E dequeue();
poll 方法,非阻塞方法,队列没有元素返回 null,否则调用 dequeue 出队。
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) ? null : dequeue();
} finally {
lock.unlock();
}
}
take 方法,阻塞方法,队列空时,会一直等待,直到被其他线程唤醒,唤醒后调用 dequeue 出队。
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}
总结:
ArrayBlockingQueue 是一个基于循环数组的阻塞型先进先出队列,内部有 ReentrantLock 实现线程安全,由 Condition 的 await 和 signal 实现等待唤醒功能。
LinkedBlockingQueue
和 ArrayBlockingQueue 有着同样的方法和性质,最大的不同是基于单向链表结构来保存数据的,是无界的。
LinkedBlockingDeque
是加强版的 LinkedBlockingQueue,内部维护一个双向链表来保存数据。
入队方法:
offer(E e)、offerFirst(E e)、offerLast(E e)
put(E e)、putFirst(E e)、putLast(E e)
出队方法:
poll()、pollFirst()、pollLast()
take()、takeFirst()、takeLast()
LinkedBlockingDeque 和 LinkedBlockingQueue 总结:
相同点:
基于链表;
容量可选,不设置的话,默认 int 最大值;
不同点:
LinkedBlockingDeque 是双向链表,LinkedBlockingQueue 是单向链表;
LinkedBlockingQueue 出队入队只能是先进先出;
LinkedBlockingDeque 可以任意选择队列头或队列尾进行出队入队。
ConcurrentLinkedQueue
非阻塞型的,使用CAS的方式来实现线程安全的,性能高于 ReentranLock。
Queue、Deque
实现 Deque 用的是双向链表。
实现 Queue 用的是单向链表。
LinkedList
定义:
package java.util;
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
同时具有 List 和 Queue 功能,是一个双向链表结构,并发访问不是线程安全的。