1.介绍数组
ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection接口。底层以数组的形式保存数据(实际上可看做一个循环数组)。经常使用的操做包括 add ,offer,put,remove,poll,take,peek。并发
前三者add offer put 是插入的操做。后面四个方法是取出的操做。他们之间的区别和关联:性能
add: 内部实际上获取的offer方法,当Queue已经满了时,抛出一个异常。不会阻塞。继承
offer:当Queue已经满了时,返回false。不会阻塞。接口
put:当Queue已经满了时,会进入等待,只要不被中断,就会插入数据到队列中。会阻塞,能够响应中断。队列
取出方法中 remove和add相互对应。也就是说,调用remove方法时,假如对列为空,则抛出一场。另外的,poll与offer相互对应。take和put相互对应。peek方法比较特殊,前三个取出的方法,都会将元素从Queue的头部溢出,可是peek不会,实际上只是,获取队列头的元素。peek方法也不会阻塞。当队列为空时,直接返回Null。rem
2.对比LinkedBlockingQueue源码
LinkedBlockingQueue也是一个阻塞式的队列,与ArrayBlockingQueue的区别是什么呢?io
LinkedBlockingQueue保存元素的是一个链表。其内部有一个Node的内部类,其中有一个成员变量 Node next。就这样造成了一个链表的结构,要获取下一个元素,只要调用next就能够了。而ArrayBlockingQueue则是一个数组。变量
LinkedBlockingQueue内部读写(插入获取)各有一个锁,而ArrayBlockingQueue则读写共享一个锁。
3.选择LinkedBlockingQueue仍是ArrayBlockingQueue
我的感受大多数场景适合使用LinkedBlockingQueue。在JDK源码当中有说明,LinkedBlockingQueue比ArrayBlockingQueue有更高的吞吐量,可是性能表现更难预测(也就是说相比ArrayBlockingQueue性能表现不稳定,可是也很稳定了)。
为何会有吞吐量的区别,我的觉得多是ArrayBlockingQueue两个锁的缘故,在大量并发的状况下,插入和读取都不少时,就会形成一点的时间浪费。
还有一点,应为LinkedBlockingQueue建立时,默认会直接建立一个Integer.MAX_VALUE的数组,当插入少,读取多时,就会形成很大的空间浪费。而LinkedBlockingQueue实际上实在等须要的时候才会建立一个Node节点。