BlockingQueue
BlockingQueue是线程安全的存取队列,继承了Queue。
使用场景
消费者生产者模式。
- 生产者,一直会往队列里扔数据,直到队列满了,开始阻塞,等待消费者取数据。
- 消费者,一直会从队列里取数据,直到队列空了,开始阻塞,等待生产者扔数据。
接口
插入方法
- add:阻塞队列满了,抛出IllegalStateException异常。成功返回true。
- offer:插入成功,返回true,插入失败,返回false。
- put:阻塞队列满了,就等到,可被中断,抛出InterruptedException异常
移除方法
- remove:成功返回true,为空抛出NoSuchElementException异常
- poll:如果队列不为空,移除并返回头结点,如果队列为空,返回null
- take:如果队列不为空,移除并返回头结点,如果队列为空,则等待,可被中断,抛出InterruptedException异常
检查方法:
- element:如果队列不为空,返回头结点但不删除,如果队列为空,抛出NoSuchElementException异常。
- peek:如果队列不为空,返回头结点但不删除,如果队列为空,返回null
子类
- ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。
- LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。
- PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。
- DelayQueue:一个使用优先级排序实现的无界阻塞队列。
- SynchronousQueue:一个不存储元素的阻塞队列。
- LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
- LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
ArrayBlockingQueue
先进先出,初始化必须给数组大小,只有一个锁。
ArrayBlockingQueue数据结构
- Object[] items:存放元素的数组
- int takeIndex:下一个读操作的位置
- int putIndex:下一个写操作的位置
- int count:数组中元素的数量
- ReentrantLock lock:同步器
- Condition notEmpty:数组空了,读等待。写的时候,唤醒
- Condition notFull:数组满了,写等待。读的时候,唤醒
ArrayBlockingQueue原理
put先放入数组,满了请求放入Condition等待数组空。take相反,数组空了,请求放入队列,等待队列有内容。
LinkedBlockingQueue
先进先出,初始化没有给链表带下,默认为Integer.MAX_VALUE,有两个锁。
LinkedBlockingQueue与ArrayBlockingQueue
- 链表是2个锁,读写各一个,数组的是1个锁
- 链表操作时需要封装成node,产生大量的node,GC耗时,数组直接操作,性能更高
- 链表的生产者的速度大于消费者时,可能内存溢出
PriorityBlockingQueue
可以直接通过Comparator或者Collection的Comparator进行排序,一个锁。
DelayQueue
DelayQueue中的对象必须实现Delayed接口,延时取元素。
使用场景:
- 订单到期未付款,取消订单
- 删除过期的缓存
SynchronousQueue
因为不存储数据,所以每一次put,都要等待一个take。
LinkedTransferQueue
先进先出,如果消费者在等待接收元素,transfer方法把元素直接给消费者,如果没有,则放对队列的尾节点,并等到消费结束后返回。tryTransfer无论消费者是否消费,都直接返回。
LinkedBlockingDeque
头部和尾部,都可以添加或移除元素。工作密取,就是用这个
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。