队列总结(四)ArrayBlockingQueue

ArrayBlockingQueue

比较简单,基于数组实现的有界阻塞队列。BlockingQueue接口中有介绍,所有该接口实现都是线程安全的。 所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。

    public ArrayBlockingQueue(int capacity) {
        this(capacity, false);
    }
    
    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();
    }

很显然,ArrayBlockingQueue的线程安全是基于lock与condition实现的,且支持可选的公平与非公平策略,这部分知识就不在这里介绍了。

    /** The queued items */
    final Object[] items;

    /** items index for next take, poll, peek or remove */
    int takeIndex;

    /** items index for next put, offer, or add */
    int putIndex;

    /** Number of elements in the queue */
    int count;

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

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

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

这里关注一下putIndex,takeIndex,分别对应入队和出队。
putIndex,下一个入队元素的下标,队列null或已满时置为0
takeIndex,下一次移除操作对应的元素的下标

    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();
    }
    
    private E dequeue() {
        // assert lock.getHoldCount() == 1;
        // assert items[takeIndex] != null;
        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();
        notFull.signal();
        return x;
    }

ArrayBlockingQueue支持在迭代的过程中不通过迭代器对队列的结构做出修改(但也仅限于当前线程,迭代过程中是全称加锁的),不会抛出ConcurrentModificationException,但是迭代结果不会受影响,保持迭代开始时的数据。

关于该队列的迭代器,实现比较麻烦,不是很想去关心,暂且放下。
这个类确实比较简单,就不多写了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值