比起ArrayBlockingQueue,LinkedBlockingQueue应该是最被大家常用的阻塞队列,LinkedBlockingQueue是基于链表的一种可选容量的阻塞队列,也就是说,在构造LinkedBlockingQueue实例的时候,你可以像ArrayBlockingQueue那样指定队列大小,也可以不指定大小(这时候默认就是Integer.MAX_VALUE),指定队列的大小是为了防止队列过度的扩张,导致内存被过度占用或溢出。链表的节点是在每一次插入时动态的创建的,除非这会导致队列超出容量限制。LinkedBlockingQueue的容量在实例被构造完成之后也是不允许被更改的。

与ArrayBlockingQueue一样LinkedBlockingQueue不允许插入null值,也是先进先出FIFO队列,队列的头部是队列中存在时间最长的元素,新元素被插入到队尾,队列出队从头部开始。与ArrayBlockingQueue相比,LinkedBlockingQueue通常具有更高的吞吐量,但在大多数并发应用程序中性能的可预测性较差。

LinkedBlockingQueue采用了“双锁队列” 算法,元素的入队和出队分别由putLock、takeLock两个独立的可重入锁来实现。所以比起ArrayBlockingQueue明显提高了吞吐量。

源码分析

先看看其成员变量:

 1 static class Node<E> {
 2     E item;
 3 
 4     /**
 5      * One of:
 6      * - the real successor Node
 7      * - this Node, meaning the successor is head.next
 8      * - null, meaning there is no successor (this is the last node)
 9      */
10     Node<E> next;
11 
12     Node(E x) { item = x; }
13 }
14 
15 /** The capacity bound, or Integer.MAX_VALUE if none */
16 private final int capacity;
17 
18 /** Current number of elements */
19 private final AtomicInteger count = new AtomicInteger();
20 
21 /**
22  * Head of linked list.
23  * Invariant: head.item == null
24  */
25 transient Node<E> head;
26 
27 /**
28  * Tail of linked list.
29  * Invariant: last.next == null
30  */
31 private transient Node<E> last;
32 
33 /** Lock held by take, poll, etc */
34 private final ReentrantLock takeLock = new ReentrantLock();
35 
36 /** Wait queue for waiting takes */
37 private final Condition notEmpty = takeLock.newCondition();
38 
39 /** Lock held by put, offer, etc */
40 private final ReentrantLock putLock = new ReentrantLock();
41 
42 /** Wait queue for waiting puts */
43 private final Condition notFull = putLock.newCondition();
View Code

相关文章:

  • 2021-12-26
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-11
  • 2021-12-21
  • 2021-11-20
  • 2022-12-23
猜你喜欢
  • 2021-08-14
  • 2022-01-11
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案