ArrayBlockingQueue和LinkedBlockingQueue的区别与联系

目录

相同点

不同点

1、由上图可以看出,他们的锁机制不同

2、他们的底层实现机制也不同

3、构造时的区别

4、统计元素的个数

其他问题

5 、LinkedBlockingQueue双锁带来的好处?

6、为何ArrayBlockingQueue无法实现锁分离机制?


相同点

1、LinkedBlockingQueue和ArrayBlockingQueue都实现了BlockingQueue接口;

2、LinkedBlockingQueue和ArrayBlockingQueue都是可阻塞的队列

  内部都是使用ReentrantLock和Condition来保证生产和消费的同步;

  当队列为空,消费者线程被阻塞;当队列装满,生产者线程被阻塞;

       使用Condition的方法来同步和通信:await()和signal()

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系
LinkedBlockingQueue底层

 

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系
ArrayBlockingQueue底层

 


不同点

1、由上图可以看出,他们的锁机制不同

  LinkedBlockingQueue中的锁是分离的,生产者的锁putLock,消费者的锁takeLock

  而ArrayBlockingQueue生产者和消费者使用的是同一把锁

2、他们的底层实现机制也不同

  LinkedBlockingQueue内部维护的是一个链表结构:

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系

       在生产和消费的时候,需要创建Node对象进行插入或移除,大批量数据的系统中,其对于GC的压力会比较大。

  而ArrayBlockingQueue内部维护了一个数组:

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系

      在生产和消费的时候,是直接将枚举对象插入或移除的,不会产生或销毁任何额外的对象实例。

3、构造时的区别

  LinkedBlockingQueue有默认的容量大小为:Integer.MAX_VALUE,当然也可以传入指定的容量大小。

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系

        ArrayBlockingQueue在初始化的时候,必须传入一个容量大小的值

   观察其提供的构造方法就能知道:

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系

 

4、统计元素的个数

         LinkedBlockingQueue中使用了一个具有原子性的AtomicInteger对象来统计元素的个数。

     

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系

         ArrayBlockingQueue则使用int类型来统计元素

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系

       

 


其他问题

5 、LinkedBlockingQueue双锁带来的好处?

       

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系
LinkedBlockingQueue底层的put()方法实现

 

6、为何ArrayBlockingQueue无法实现锁分离机制?

       我们先来看看ArrayBlockingQueue中的enqueue入队操作:

ArrayBlockingQueue和LinkedBlockingQueue的区别与联系

        这也解释了为何ArrayBlockingQueue无法实现锁分离机制,ArrayBlockingQueue底层的数组是一个循环数组,循环数组的存放地址会改变,每次操作后数组元素的下标都不确定,这样的操作无法进行原子化操作,简而言之就是CAS操作时内存位置的值和预期原值不相匹配,无法通过CAS机制的校验。