美文网首页程序员
Java - ArrayBlockingQueue设计原理

Java - ArrayBlockingQueue设计原理

作者: 夹胡碰 | 来源:发表于2020-12-30 00:26 被阅读0次

    ArrayBlockingQueueLinkedBlockingQueue都是BlockingQueue的实现,从名字就可以看出ArrayBlockingQueue底层是基于数组的,LinkedBlockingQueue底层是基于链表的。
    ArrayBlockingQueue比较特殊,它的链表是一个环形链表,内部维护了putIndextakeIndex索引,用来指定puttake的位置,如下所示:

    这么设计的好处是通过移动指针来替代数组元素移动,极大的减少了数组移动带来的性能损耗。

    下面将通过源码介绍:

    1. put方法

    加锁和阻塞机制与LinkedBlockingQueue相同,主要关注enqueue方法

    public void put(E e) throws InterruptedException {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == items.length) // 数据满了的时候,不会进入enqueue方法
                notFull.await();
            enqueue(e);
        } finally {
            lock.unlock();
        }
    }
    
    • enqueue
    1. items[putIndex] = x;说明内部数组记录一个putIndex索引,用于添加元素。
    2. if (++putIndex == items.length),添加之后进行++putIndex指针后移,并当指针越界时重置为0位置,形成环形链表。
    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();
    }
    
    2. take方法
    public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == 0)
                notEmpty.await();
            return dequeue(); // 执行take
        } finally {
            lock.unlock();
        }
    }
    
    • dequeue
      记录takeIndex位置,进行take操作
    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;
    }
    

    相关文章

      网友评论

        本文标题:Java - ArrayBlockingQueue设计原理

        本文链接:https://www.haomeiwen.com/subject/ixkcoktx.html