并发队列
并发队列
目录
为什么要使用队列
并发队列简介
- Queue
- BlockingQueue(阻塞队列)
阻塞队列BlockQueue
什么是阻塞队列
-
简介、地位
- 阻塞队列是具有阻塞功能的队列,所以它首先是一个队列其次是具有阻塞功能。
- 通常,阻塞队列的一端是给生产者放数据用,另一端给消费者拿数据用。阻塞队列是线程安全的,所以生产者和消费者都可以是多线程的
-
阻塞功能:最有特色的两个带有阻塞功能的方法是
- take()方法:获取并移除队列的头结点,一旦如果执行take的时候,队列里无数据,则阻塞,直到队列里有数据。
- put()方法:插入元素。但是如果队列已满,那么就无法继续插入,则阻塞,直到队列里有了空闲空间。
-
是否有界(容量有多大):这是一个非常重要的属性,无界队列意味着里面可以容纳非常多(Integer.MAX VALUE,约为2的31次,是非常大的一个数,可以近似认为是无限容量)。
-
阻塞队列和线程池的关系:阻塞队列是线程池的重要组成部分
BlockingQueue主要方法
- put、take
- add、remove、element
- offer、poll、peek
ArrayBlockingQueue
- 有界
- 指定容量
- 公平:还可以指定是否需要保证公平,如果想保证公平的话那么等待了最长时间的线程会被优先处理,不过这会同时带来一定的性能损耗。
LinkedBlockingQueue
- 无界
- 容量Integer.MAX_VALUE
- 内部结构:Node、两把锁。
PriorityBlockingQueue
- 支持优先级
- 自然顺序(而不是先进先出)
- 无界队列
- PriorityQueue的线程安全版本
SynchronousQueue
- 它的容量为0
- 需要注意的是,SynchronousQueue的容量不是1而是0,因为SynchronousQueue不需要去持有元素,它所做的就是直接传递(direct handoff)
SynchronousQueue注意点
DelayQueue
- 延迟队列,根据延迟时间排序
- 元素需要实现Delayed接口,根据排序规则
非阻塞队列ConcurrentLinkedQueue
如何选择自己的队列
- 边界
- 空间
- 吞吐量