队列真的是一个非常nice的数据结构,有序,规则,可以给与缓冲,就像人们心中那种秩序社会一样,那么这期小威哥就来粗浅的聊聊java中那些常见的quene。
2:各种常见quene对比
2.1:对比表格
队列 |
数据结构 |
边界 |
并发特征 |
特点 |
ArrayBlockingQueue |
数组 |
有界(因为是数组) |
阻塞 |
简单,数组结构 |
LinkedBlockingQueue |
链表 |
可以指定大小(默认为MaxInt) |
阻塞 |
链表 |
ConcurrentLinkedQueue |
链表 |
无界 |
cas无锁 |
无锁,多消费者 |
DelayQueue |
堆 |
无界 |
阻塞 |
实现延时效果 |
2.2:有界无界,数据结构,并发性
2.3:使用场景选择
- 可以预估队列有界,可以选择ArrayBlockingQueue
- 单生产者,单消费者 用 LinkedBlockingqueue
- 多生产者,单消费者 用 LinkedBlockingqueue
- 单生产者 ,多消费者 用 ConcurrentLinkedQueue
- 多生产者 ,多消费者 用 ConcurrentLinkedQueue
- 如果是有延时效果,可以选 DelayQueue
3:ConcurrentLinkedQuene的一个坑
ConcurrentLinkedQuene的size方法请千万不要使用!!!!最好用isEmpty来代替,因为size方法会去遍历链表节点来确定size
源码如下:
4:Disruptor环形队列
Disruptor队列是一个次世代的环形jvm队列,效率非常高,被log4j2所使用,关于这点可以看我的另一篇文章Disruptor队列,这里就不再赘述了。
5:分布式消息队列
当然,我们现在的很多项目或者应用都是大规模的使用了分布式的服务,不论redis,dubbo,springcloud,等等。所以很多jvm的内存队列其实满足不了我们的需求,这个时候我们就需要使用分布式的消息队列。
这里我推荐使用三个分布式消息队列
- redis : 大多数人以为redis只是一个缓存kv数据库,其实redis可以使用监听的功能实现一个非常轻量级的消息队列。
但是redis实现的消息队列无法实现持久化,所以万一断电就丢了,所以建议如果传输一些无关紧要的埋点啊什么统计数据啊可以使用一下。
- rocketmq:阿里出品的非常全面的消息队列,api也很友好,推荐使用,记得需要关注业务幂等哦!!
- kafka:划时代的消息队列,引领了目前的消息队列潮流,超高的吞吐量,很适合广告,流式处理啊,日志记录啊等等高吞吐场景。但是如果是金融等高可靠性的场景还是使用rocketmq并且同步刷盘!
6:总结
队列真的是一种万金油,简单易用而且使用场景丰富,可延时,可削峰,可异步,融合编程的很多经典又精髓的感念,是开发过程中的利器!大家要多多合理使用!
原文
https://juejin.im/post/5dee37ad51882512657ba41f