ptibly();
23 try {
24 while (count == items.length)
25 notFull.await();
26 enqueue(e);
27 } finally {
28 lock.unlock();
29 }
30 }
31
32 // 实际上的添加方法,添加成功后会唤醒一个等待删除元素的线程。
33 private void enqueue(E x) {
34 final Object[] items = this.items;
35 items[putIndex] = x;
36 if (++putIndex == items.length)
37 putIndex = 0;
38 count++;
39 notEmpty.signal();
40 }
删除元素
ArrayBlockingQueue提供了poll()方法和take()方法两种方式删除元素。
poll()方法删除失败会立即返回false,并且添加过程中不允许被其他线程中断。
take()方法删除失败会等待,并且在删除过程中可以被其他线程中断,抛出InterruptedException异常。
1 // 不允许被其他线程中断,删除失败则立即返回null。
2 public E poll() {
3 final ReentrantLock lock = this.lock;
4 lock.lock();
5 try {
6 return (count == 0) ? null : dequeue();
7 } finally {
8 lock.unlock();
9 }
10 }
11
12 // 允许被其他线程中断,抛出InterruptedException,并且删除失败会等待。
13 public E take() throws InterruptedException {
14 final ReentrantLock lock = this.lock;
15 lock.lockInterruptibly();
16 try {
17 while (count == 0)
18 notEmpty.await();
19 return dequeue();
20 } finally {
21 lock.unlock();
22 }
23 }
24
25 // 实际上的删除方法,删除成功后会唤醒一个等待添加元素的线程。
26 private E dequeue() {
27 final Object[] items = this.items;
28 @SuppressWarnings("unchecked")
29 E x = (E) items[takeIndex];
30 items[takeIndex] = null;
31 if (++takeIndex == items.length)
32 takeIndex = 0;
33 count--;
34 if (itrs != null)
35 itrs.elementDequeued();
36 notFull.signal();
37 return x;
38 }
LinkedBlockingQueue
说明
LinkedBlockingQueue是一个单向链表实现的阻塞队列。该队列按FIFO(先进先出)排序元素,新元素插入到队列的尾部,并且队列获取操作会获得位于队列头部的元素。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。
LinkedBlockingQueue是可选容量的(防止过度膨胀),即可以指定队列的容量。如果不指定,默认容量大小等于Integer.MAX_VALUE。
LinkedBlockingQueue实现了BlockingQueue接口,它支持多线程并发。当多线程竞争同一个资源时,某线程获取到该资源之后,其它线程需要阻塞等待。
LinkedBlockingQueue在实现多线程对竞争资源的互斥访问时,对于插入和取出操作分别使用了不同的锁。此外,插入锁putLock和非满条件notFull相关联,取出锁takeLock和非空条件notEmpty相关联。通过notFull和notEmpty更细腻的控制锁。
属性
1 head是链表的表头。取出数据时,都是从表头head处插入。
2 last是链表的表尾。新增数据时,都是从表尾last处插入。
3 count是链表的实际大小,即当前链表中包含的节点个数。
4 capacity是列表的容量,它是在创建链表时指定的。
5 putLock是插入锁。
6 takeLock是取出锁。
7 notEmpty是非空条件。
8 notFull是非满条件。
构造方法
1 // 创建一个容量为Integer.MAX_VALUE的LinkedBlockingQueue。
2 LinkedBlockingQueue()
3 // 创建一个指定容量的LinkedBlockingQueue。
4 LinkedBlockingQueue(int capacity)
5 // 创建一个容量是Integer.MAX_VALUE的LinkedBlockingQueue,最初包含给定collection的元素,元素按该collection迭代器的遍历顺序添加。
6 LinkedBlockingQueue(Collection<? extends E> c)
其他方法
1 // 将指定元素插入到此队列的尾部,如果队列已满,则等待。
2 void put(E e)
3 // 将指定元素插入到此队列的尾部,如果队列已满,则返回false。
4 boolean offer(E e)
5 // 将指定元素插入到此队列的尾部,如果队列已满,则等待指定的时间。
6 boolean offer(E e, long timeout, TimeUnit unit)
7 // 获取并移除此队列的头部,如果队列为空,则等待。
8 E take()
9 // 获取并移除此队列的头部,如果队列为空,则返回null。
10 E poll()
11 // 获取并移除此队列的头部,如果队列为空,则等待指定的时间。
12 E poll(long timeout, TimeUnit unit)
13 // 获取但不移除此队列的头,如果此队列为空,则返回null。
14 E peek()
15 // 返回在队列中的元素上按适当顺序进行迭代的迭代器。
16 Iterator<E> iterator()
ConcurrentLinkedQueue
说明
ConcurrentLinkedQueue是线程安全的队列,它适用于“高并发”的场景。ConcurrentLinkedQueue使用CAS来保证更新的线程安全,是一个非阻塞队列。
ConcurrentLinkedQueue是一个基于链表的无界线程安全队列,按照FIFO(先进先出)原则对元素进行排序。队列元素中不可以放置null元素(内部实现的特殊节点除外)。
构造方法
1 // 创建一个最初为空的ConcurrentLinkedQueue。
2 ConcurrentLinkedQueue()
3 // 创建一个最初包含给定collection元素的ConcurrentLinkedQueue,按照此collection |