java并发容器-BlockingQueue

线程安全的阻塞队列,用来处理 生产者-消费者 问题。
当队列容器满时,生产者线程被阻塞直到队列未满。
当队列容器为空时,消费者线程阻塞直到队列非空。

主要介绍BlockingQueue下三个实现类

1。ArrayBlockingQueue

底层使用数组来实现的有界阻塞队列。
一旦构造方法确定了数组容量大小后就不能改变,使用可重入锁来控制,
构造方法中可以选择实现公平锁还是非公平锁。
公平锁的意思是先等待的线程最先访问到ArrayBlockingQueue。
默认是非公平锁,因为公平锁会降低队列的吞吐性能。

    public ArrayBlockingQueue(int capacity, boolean fair) {
        if (capacity <= 0)
            throw new IllegalArgumentException();
        this.items = new Object[capacity];
        lock = new ReentrantLock(fair);
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
    }

不管是插入操作还是读取操作,都要获取到锁才能操作。

    /** Main lock guarding all access */
    final ReentrantLock lock;

    /** Condition for waiting takes */
    private final Condition notEmpty;

    /** Condition for waiting puts */
    private final Condition notFull;

2。LinkedBlockingQueue

底层使用单向链表实现的无界阻塞队列。
默认容量大小为Integer.MAX_VALUE
一般需要指定容量大小,不然会消耗大量内存。

指定容量大小可以当做有界阻塞队列来使用
不指定大小则当做意义上的无界阻塞队列。

  public LinkedBlockingQueue() {
        this(Integer.MAX_VALUE);
    }

3。PriorityBlockingQueue

一个支持优先级的无界阻塞队列
默认情况下按照自然顺序对元素进行排序
底层使用数组来实现,默认初始为11大小的数组,
后面随着元素增加会不断扩容。

    public PriorityBlockingQueue(int initialCapacity,
                                 Comparator comparator) {
        if (initialCapacity < 1)
            throw new IllegalArgumentException();
        this.lock = new ReentrantLock();
        this.notEmpty = lock.newCondition();
        this.comparator = comparator;
        this.queue = new Object[initialCapacity];
    }

添加元素时判断是否当前元素个数已经大于数组容量了,就进行扩容

        while ((n = size) >= (cap = (array = queue).length))
            tryGrow(array, cap);

新的容量是看旧容量的多少来具体分配的,
旧容量越小增长的快一点(增长(oldCap + 2) ),
旧容量大一点的旧增长的慢一点(增长(oldCap >> 1))

                int newCap = oldCap + ((oldCap < 64) ?
                                       (oldCap + 2) : // grow faster if small
                                       (oldCap >> 1));

你可能感兴趣的:(java并发容器-BlockingQueue)