ArrayBlockingQueue
ArrayBlockingQueue
ArrayBlockingQueue,一个由数组实现的有界阻塞队列。该队列采用FIFO的原则对元素进行排序添加的,(删除添加可以理解为循环的数组添加在前删除在后追赶)。 ArrayBlockingQueue为有界且固定,其大小在构造时由构造函数来决定,确认之后就不能再改变了。支持公平策略
定义
ArrayBlockingQueue内部使用可重入锁ReentrantLock + Condition来完成多线程环境的并发操作。
1 |
|
三个构造函数
1 |
|
三个常用添加方法
add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会抛出IllegalStateException异常。
1
Exception in thread "main" java.lang.IllegalStateException: Queue full
put:添加元素到队列里,如果容量满了会阻塞直到容量不满。内部直接调用的
enqueue
offer:添加元素到队列里,添加成功返回true,添加失败返回false,下边的逻辑依旧可以执行。
add
内部调用offer(E e)
1
2
3
4
5
6
7
8
9public boolean add(E e) {
return super.add(e);
}
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}offer
核心是enqueue
方法,做了真正的入队操作1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26public boolean offer(E e) {
checkNotNull(e);//检查e是否为null,为null抛出异常。
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}
private void enqueue(E x) {
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length)//队列已满
putIndex = 0;
count++;
notEmpty.signal();//唤醒出队
}
三个常用删除方法
remove:删除队列头部元素,删除成功返回该元素,队列为空删除会抛出NoSuchElementException异常。
1
Exception in thread "main" java.util.NoSuchElementException
take:删除队列头部元素,如果队列为空,一直阻塞到队列有元素并删除。
poll:删除队列头部元素,如果队列为空,返回null,否则返回元素,下边逻辑依旧可以执行。可以传入时间,等待n时间,没有元素就返回null。
remove
底层最后调用了poll()
,take
和poll
底层最后执行的dequeue
,二者区别仅在于poll
返回null,take
挂起。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//take
while (count == 0)
notEmpty.await();
return dequeue();
//poll
return (count == 0) ? null : dequeue();
private E dequeue() {
final Object[] items = this.items;
@SuppressWarnings("unchecked")
E x = (E) items[takeIndex];
items[takeIndex] = null;
if (++takeIndex == items.length)
takeIndex = 0;
count--;
if (itrs != null)
itrs.elementDequeued();//内部迭代器需要移动元素位置,因为默认删除删的是头部,不处理迭代的话,迭代头部为null
notFull.signal();
return x;
}
ArrayBlockingQueue
http://www.muzili.ren/2022/06/11/ArrayBlockingQueue/