写点什么

LinkedBlockingQueue 源码分析 - 初始化

作者:zarmnosaj
  • 2022 年 7 月 06 日
  • 本文字数:1775 字

    阅读完需:约 6 分钟

LinkedBlockingQueue 特点

LinkedBlockingQueue 通常叫做链表阻塞队列,从命名可以知道,其底层数据是链表,且队列是可阻塞的。LinkedBlockingQueue 的特点:


  1. 基于链表实现的阻塞队列,底层的数据结构为链表

  2. 基于链表实现先入先出的队列,新元素放在队尾,从队头部获取元素

  3. 链表大小在初始化的时候可以设置大小,默认为 Integer 的最大值

  4. 可以使用 Iterator 进行迭代

属性

源码:


public class LinkedBlockingQueue<E> extends AbstractQueue<E>        implements BlockingQueue<E>, java.io.Serializable {    private static final long serialVersionUID = -6903933977591709194L;        /**     * Linked list node class     */    static class Node<E> {        E item;
/** * One of: * - the real successor Node * - this Node, meaning the successor is head.next * - null, meaning there is no successor (this is the last node) */ Node<E> next;
Node(E x) { item = x; } } /** The capacity bound, or Integer.MAX_VALUE if none */ private final int capacity;
/** Current number of elements */ private final AtomicInteger count = new AtomicInteger();
/** * Head of linked list. * Invariant: head.item == null */ transient Node<E> head;
/** * Tail of linked list. * Invariant: last.next == null */ private transient Node<E> last;
/** Lock held by take, poll, etc */ private final ReentrantLock takeLock = new ReentrantLock();
/** Wait queue for waiting takes */ private final Condition notEmpty = takeLock.newCondition();
/** Lock held by put, offer, etc */ private final ReentrantLock putLock = new ReentrantLock();
/** Wait queue for waiting puts */ private final Condition notFull = putLock.newCondition();
......}
复制代码


static class Node<E> 表示链表的元素节点


Node<E> next; 表示当前元素指向的下一个节点,如果为 null,则表示当前节点为最后一个节点


private final int capacity;链表的容量,默认 Integer.MAX_VALUE


private final AtomicInteger count = new AtomicInteger();链表已有元素大小,使用 AtomicInteger,所以是线程安全的


transient Node<E> head; 链表头


private transient Node<E> last;链表尾


private final ReentrantLock takeLock = new ReentrantLock(); take 时的锁


private final Condition notEmpty = takeLock.newCondition();take 的条件队列


private final ReentrantLock putLock = new ReentrantLock();put 时的锁


private final Condition notFull = putLock.newCondition();put 的条件队列


总结:设计了两把锁,一个是 take 锁,一个是 put 锁,目的是为了让两个操作互相不干扰,同步进行

初始化

源码:


    public LinkedBlockingQueue() {        this(Integer.MAX_VALUE);    }
public LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node<E>(null); }
public LinkedBlockingQueue(Collection<? extends E> c) { this(Integer.MAX_VALUE); final ReentrantLock putLock = this.putLock; putLock.lock(); // Never contended, but necessary for visibility try { int n = 0; for (E e : c) { if (e == null) throw new NullPointerException(); if (n == capacity) throw new IllegalStateException("Queue full"); enqueue(new Node<E>(e)); ++n; } count.set(n); } finally { putLock.unlock(); } }
复制代码


源码中提供了三种初始化的方式:第一种:使用默认的 Integer 的最大值进行初始化第二种:指定链表容量大小初始化第三章:使用已有集合数据进行初始化

发布于: 刚刚阅读数: 4
用户头像

zarmnosaj

关注

靡不有初,鲜克有终 2020.02.06 加入

成都后端混子

评论

发布
暂无评论
LinkedBlockingQueue源码分析-初始化_7月月更_zarmnosaj_InfoQ写作社区