Collection的子类,除了List和Map外,还有一类集合Queue,它是在两端出入的List,所以也可以用数组或链表来实现。队列可分为两类,普通队列和线程安全队列。普通队列包含LinkedList,ArrayDeque。
线程安全队列又分为无界队列和有界队列,有界队列常用于类似于生产者消费者的需求。
线程安全队列:
- ConcurrentLinkedQueue/ConcurrentLinkedDeque:基于链表的无界的并发优化的Queue,实现了依赖于CAS的无锁算法。
- LinkedBlockingQueue/LinkedBlockingDeque:基于链表的可选定长的并发优化的BlockingQueue。利用链表的特征,分离了takeLock与putLock两把锁,继续用notEmpty、notFull管理队列满或空时的阻塞状态。
- ArrayBlockingQueue:定长的并发优化的BlockingQueue,基于循环数组实现。有一把公共的读写锁与notFull、notEmpty两个Condition管理队列满或空时的阻塞状态。
- SynchronousQueue:
Executors.newCachedThreadPool()
中所使用的队列,只有当队列有由take()
方法或者poll(timeout, unit)
进入等待状态时,才能由offer()
和add()
把element添加到队列中。
Queue
|
|
Queue继承自Collection并添加了6个方法,此6个方法分可为3组:
- add / offer
- remove / poll
- element / peek
前后两个方法为一组,方法的操作基本一样,所不同的是前一个方法会抛出异常,而后面的方法则不会。
AbstractQueue
|
|
AbstractQueue对Queue中的部分方法做了’实现’,add、remove、element方法分别调用了offer、poll、peek。
BlockingQueue
|
|
BlockingQueue在Queue的基础上,添加了put、take、带超时的offer和poll方法。
take vs poll vs peek
- take: Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.
获取并且删除queue中的第一个元素,如果queue中没有element,则会一直等待直到queue中有可用的元素。 - poll: Retrieves and removes the head of this queue, or returns null if this queue is empty.
获取并且删除queue中的第一个元素,如果queue为空则返回null。 - peek: Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.
获取queue中的第一个元素,但并不删除它,如果queue为空则返回null。
LinkedBlockingQueue
|
|
Example:
|
|
Executors.newFixedThreadPool(int)
和Executors.newSingleThreadExecutor()
都使用了LinkedBlockingQueue。
LinkedBlockingDeque
|
|
和LinkedBlockingQeque不同,LinkedBlockingDeque同时提供了对队列头和尾的相关操作。
BlockingDeque
|
|
Example:
|
|