1、什么是队列
Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构,类似火车站排队买票。
从图中可以看出,Queue接口与List、Set同一级别,都是继承了Collection接口。
2、队列的常用方法
2.1、Queue中方法简述
方法 | 操作说明 | 是否抛异常 |
---|---|---|
add | 增加一个元素 | 当队列长度限制,抛出 IllegalStateException,更推荐使用offer |
offer | 添加一个元素 | 当队列长度限制,达到上限,会抛出异常 |
remove | 如果该队列包含一个或多个这样的元素,则删除满足 o.equals(e) 的元素 e | 此方法与 poll 的不同之处仅在于,如果此队列为空,它会引发异常。 |
poll | 移除并返回队列头部的元素 | 如果此队列为空,则返回 null。 |
element | 检索但不删除此队列的头部。 | 此方法与 peek 的不同之处仅在于,如果此队列为空,它会引发异常。 |
peek | 检索但不删除此队列的头部 | 如果此队列为空,则返回 null。 |
2.2、BlockingQueue中方法简述
方法 | 操作说明 | 是否抛异常 |
---|---|---|
add | 增加一个元素 | 当队列长度限制,抛出 IllegalStateException,更推荐使用offer |
offer | 添加一个元素 | 当队列长度限制,达到上限,会抛出异常 |
put | 指定的元素插入此队列 | 如果队列满,则阻塞 |
take | 返回队列头部的元素 | 如果队列为空,则阻塞 |
poll | 移除并返回队列头部的元素 | 可以设置时长 |
remove | 如果该队列包含一个或多个这样的元素,则删除满足 o.equals(e) 的元素 e | 元素为空,或者元素类型不匹配则抛出异常 |
contains | 如果此队列包含指定的元素,则返回 true。 | |
drainTo | 从此队列中移除所有可用元素并将它们添加到给定集合中。 | 比轮询方式添加到集合中效率高 |
2.3、AbstractQueue中方法简述
方法 | 操作说明 | 是否抛异常 |
---|---|---|
add | 增加一个元素 | 当队列长度限制,抛出 IllegalStateException,更推荐使用offer |
remove | 如果该队列包含一个或多个这样的元素,则删除满足 o.equals(e) 的元素 e | 此方法与 poll 的不同之处仅在于,如果此队列为空,它会引发异常。 |
element | 检索但不删除此队列的头部。 | 此方法与 peek 的不同之处仅在于,如果此队列为空,它会引发异常。 |
clear | 从此队列中删除所有元素。 此调用返回后,队列将为空。 | 这个实现反复调用 poll 直到它返回 null。 |
addAll | 将指定集合中的所有元素添加到此队列。 尝试向自身添加队列的所有内容会导致 IllegalArgumentException。 此外,如果在操作进行时修改了指定的集合,则此操作的行为未定义。 | 尝试添加元素(尤其包括空元素)时遇到的运行时异常可能会导致在引发相关异常时仅成功添加了某些元素。 |
3、阻塞队列
3.1、ArrayBlockingQueue阻塞,公平,固定长度队列
是有界的阻塞安全队列,默认是不保证线程的公平性,不允许向队列中插入null元素。
- 阻塞
- 当队列为null时,取和插入的操作都会block,并且整个队列有一把锁
- 公平
- 在构造方法中,默认ReentrantLock是非公平锁,可以指定fair=true为公平锁,AQS中非公平锁会产生锁竞争,公平锁不会产生锁竞争
- 固定长度
- 底层使用的是数组结构。因为数组需要初始化大小,所以其构造器需要输入队列的大小。并且在操作过程中数组大小不可以修改,
3.2、ConcurrentLinkedQueue无界,单端,非阻塞队列
- 无界
- 因内部存储结构是单向链表,所以可以不断新增新值
- 单端
- 非阻塞
- 因为没有容量限制,所以没有阻塞,并发情况下插入和取出的时候存在锁竞争(CAS操作),导致等待,但是不会阻塞
3.3、DelayQueue无界、单端、阻塞队列
- 无界
- 是一个支持优先级的无界阻塞队列。支持优先级是应该底层使用的是PriorityQueue队列来实现的。而PriorityQueue队列在添加元素的时候使用了siftUpComparable方法。这个对了的一个特点:支持延时获取。所以,这个队列可以运用在缓存系统的设计中。当从队列中获取到数据,说明延时时间到了。
- 单端
- 阻塞队列
- 当Delay时间未到,或队列为null时所有的”取“操作都会被阻塞,并且整个队列有一把锁
3.4、LinkedBlockingQueue有界或无界、单端、阻塞队列
- 有界或无界
- “有界”的阻塞安全队列,其底层使用的是链表的数据结构。所谓的“有界”是因为,默认队列的大小是Integer.MAX_VALUE。这个数值等于21亿+。因为这个数据太大了,也可以理解为无界的。不建议使用默认值,最好在初始化的时候,指定队列的大小。
3.5、PriorityBlockingQueue无界、单端、阻塞的优先级队列
是一个支持优先级的无界队列。支持优先级是因为使用了comparator这个接口。默认采用字典升序排序策略的。如果不想使用默认的,在初始化的时候,还可以自定义比较器的。
3.6、SynchronouseQueue无储存空间、阻塞、同步、公平(可选)队列
是一个无存储空间的阻塞同步队列。不存储元素的原因是因为,一个put操作必须等待一个take操作与之对应才可以。否则就不能继续添加元素了。默认使用非公平的。在性能上SyncQueue队列的吞吐量比LBqueu和ABQueue的性能高。
3.7、LinkedTrnsferQueue
是由链表组成的无界队列。比其他队列多了两个方法:tryTransfer、transfer
3.8、LinkedBlockingDeque:
链表组成的双端队列