LinkedBlockingQueue和ArrayBlockingQueue的比较

相同点

  1、LinkedBlockingQueue和ArrayBlockingQueue都实现了BlockingQueue接口,继承了AbstractQueue抽象类。

LinkedBlockingQueue
在这里插入图片描述
ArrayBlockingQueue
在这里插入图片描述

  2、LinkedBlockingQueue和ArrayBlockingQueue都是可阻塞的队列,内部都是使用ReentrantLock和Condition来保证生产和消费的同步;当队列为空,消费者线程被阻塞;当队列装满,生产者线程被阻塞。

LinkedBlockingQueue
在这里插入图片描述
ArrayBlockingQueue
在这里插入图片描述

  3、都是使用Condition的方法来同步和通信:await()和signal()。

不同点

1、锁机制不同:

LinkedBlockingQueue中的锁是分离的,生产者的锁为PutLock,消费者的锁为takeLock。而ArrayBlockingQueue生产者和消费者使用的是同一把锁;

LinkedBlockingQueue
在这里插入图片描述
ArrayBlockingQueue
在这里插入图片描述
2、他们的底层实现机制也不同

LinkedBlockingQueue内部维护的是一个链表结构,在生产和消费的时候,需要创建Node对象进行插入或移除,大批量数据的系统中,其对于GC的压力会比较大。而ArrayBlockingQueue内部维护了一个数组,在生产和消费的时候,是直接将枚举对象插入或移除的,不会产生或销毁任何额外的对象实例。

LinkedBlockingQueue
在这里插入图片描述在这里插入图片描述
ArrayBlockingQueue的底层:
在这里插入图片描述

3、构造方法不同:

LinkedBlockingQueue有默认的容量大小为:Integer.MAX_VALUE,当然也可以传入指定的容量大小。ArrayBlockingQueue在初始化的时候,必须传入一个容量大小的值。

LinkedBlockingQueue
在这里插入图片描述
ArrayBlockingQueue:
在这里插入图片描述

4、clear()机制不同。

LinkedBlockingQueue的clear()方法中,会加两把锁。ArrayBlockingQueue的clear()方法中只加一把锁。

LinkedBlockingQueue:

  public void clear() {
        fullyLock();
        try {
            for (Node<E> p, h = head; (p = h.next) != null; h = p) {
                h.next = h;
                p.item = null;
            }
            head = last;
            // assert head.item == null && head.next == null;
            if (count.getAndSet(0) == capacity)
                notFull.signal();
        } finally {
            fullyUnlock();
        }
    }

ArrayBlockingQueue执行clear()的机制:

 public void clear() {
        final Object[] items = this.items;
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            int k = count;
            if (k > 0) {
                final int putIndex = this.putIndex;
                int i = takeIndex;
                do {
                    items[i] = null;
                    if (++i == items.length)
                        i = 0;
                } while (i != putIndex);
                takeIndex = putIndex;
                count = 0;
                if (itrs != null)
                    itrs.queueIsEmpty();
                for (; k > 0 && lock.hasWaiters(notFull); k--)
                    notFull.signal();
            }
        } finally {
            lock.unlock();
        }
    }

5、统计元素的个数

LinkedBlockingQueue中使用了一个AtomicInteger对象来统计元素的个数,ArrayBlockingQueue则使用int类型来统计元素。
  
  LinkedBlockingQueue中统计元素个数的源码
在这里插入图片描述
ArrayBlockingQueue中统计元素个数的源码
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值