LinkedBlockingQueue和ArrayBlockingQueue 对比

相同:

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

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

 

 

不同:

 

1、队列中的同步锁机制不同

ArrayBlockingQueue中的锁是没有分离的,即生产和消费用的是同一个锁; 使用一个ReentrantLock来保证线程安全:入列和出列前都需要获取该锁。

LinkedBlockingQueue中的锁是分离的,使用两个ReentrantLock来保证线程安全:入列前需要获取到入列锁(putLock),出列前需要获取到出列锁(takeLock),实现了入列锁和出列锁的分离。

 

2、底层实现机制不同

ArrayBlockingQueue      使用一个Object数组来存储元素。

LinkedBlockingQueue    使用链表来存储元素。

 

 

3.队列的大小不同:

ArrayBlockingQueue      是有界队列,且初始化时必须指定队列的大小。

LinkedBlockingQueue    是无界队列,在初始化的时候可以指定队列的大小从而变成有界队列。默认是Integer.MAX_VALUE,当入列速度大于出列速度时可能会造成内存溢出。(也可以做手工指定大小,从而成为有界的)

 

4.在生产或消费时操作不同

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

LinkedBlockingQueue基于链表,在生产和消费的时候,需要把枚举对象转换为Node<E>进行插入或移除,会生成一个额外的Node对象,这在长时间内需要高效并发地处理大批量数据的系统中,其对于GC的影响还是存在一定的区别。

 

 

5、并发性能

ArrayBlockingQueue中生产和消费用的是同一个锁; 入列和出列前都需要获取该锁。

LinkedBlockingQueue中使用入列锁和出列锁的分离,故LinkedBlockingQueue的并发执行效率要高一些。

 

6.内存方面

ArrayBlockingQueue 用于存储队列元素的存储空间是预先分配的,使用过程中内存开销较小(无须动态申请存储空间)

LinkedBlockingQueue 用于存储队列元素的存储空间是在其使用过程中动态分配的,因此它可能会增加JVM垃圾回收的负担。

 

7.吞吐量

LinkedBlockingQueue在大多数并发的场景下吞吐量比ArrayBlockingQueue高,但是性能不稳定。

Linked queues typically have higher throughput than array-based queues but less predictable performance in most concurrent applications.

这个主要针对LinkedBlockingQueue是无界的场景来说,由于无界,所以offer以及poll的吞吐量通常比ArrayBlockingQueue高。

posted @ 2020-05-02 14:10  陈小兵  阅读(1619)  评论(1编辑  收藏  举报