1. ArrayBlockingQueue, LinkedBlockingQueue, ConcurrentLinkedQueue

ArrayBlockingQueue, LinkedBlockingQueue 继承自 BlockingQueue, 他们的特点就是 Blocking, Blocking 特有的方法就是 take() 和 put(), 这两个方法是阻塞方法, 每当队列容量满的时候, put() 方法就会进入wait, 直到队列空出来, 而每当队列为空时, take() 就会进入等待, 直到队列有元素可以 take()

ArrayBlockingQueue, LinkedBlockingQueue 区别在于 ArrayBlockingQueue 必须指定容量, 且可以指定 fair 变量, 如果 fair 为 true, 则会保持 take() 或者 put() 操作时线程的 block 顺序, 先 block 的线程先 take() 或 put(), fair 又内部变量 ReentrantLock 保证

ConcurrentLinkedQueue 通过 CAS 操作实现了无锁的 poll() 和 offer(), 他的容量是动态的, 由于无锁, 所以在 poll() 或者 offer() 的时候 head 与 tail 可能会改变, 所以它会持续的判断 head 与 tail 是否改变来保证操作正确性, 如果改变, 则会重新选择 head 与 tail. 而由于无锁的特性, 他的元素更新与 size 变量更新无法做到原子 (实际上它没有 size 变量), 所以他的 size() 是通过遍历 queue 来获得的, 在效率上是 O(n), 而且无法保证准确性, 因为遍历的时候有可能 queue size 发生了改变.

RingBuffer 是 Distruptor 中的一个用来替代 ArrayBlockingQueue 的队列, 它的思想在于长度可控, 且无锁, 只有在 blocking 的时候(没有数据的时候出队, 数据满的时候入队)会自旋. 实现原理是使用一个环形array, 生产者作为 tail, 消费者作为 head, 每生产一次 tail atomic++, 每消费一次 head atomic++, tail 不能超过 head 一圈(array size, 即队列满时 blocking), tail 不能超过自己tail一圈(即不能覆盖未被消费的值), head 不能超过 tail (即无可消费任务时 blocking), head 不能取到空值(取到空值时 blocking). blocking 使用一个 while 自旋来完成, 那么只要生产者消费者的速度相当时, 即可通过 atomicInteger(cas) 保证无锁, 而如果你需要在 blocking 的时候立即返回, 则 while 自旋都可以不需要. 相比于 ArrayBlockingQueue, 它可以绝大部分时间无锁, blocking 自旋, 相比于 concurrentLinkedQueue, 他又能做到长度限制. 代码如下:

public class RingBuffer<T> implements Serializable {/****/private static final long serialVersionUID = 6976960108708949038L;private volatile AtomicInteger head;private volatile AtomicInteger tail;private int length;final T EMPTY = null;private volatile T[] queue;public RingBuffer(Class<T> type, int length){this.head = new AtomicInteger(0);this.tail = new AtomicInteger(0);this.length = length == 0 ? 2 << 16 : length; // 默认2^16  this.queue = (T[]) Array.newInstance(type, this.length);}public void enQueue(T t){if(t == null) t= (T) new Object();// 阻塞 -- 避免多生成者循环生产同一个节点  while(this.getTail() - this.getHead() >= this.length);int ctail = this.tail.getAndIncrement();while(this.queue[this.getTail(ctail)] != EMPTY); // 自旋  this.queue[this.getTail(ctail)] = t;}public T deQueue(){T t = null;// 阻塞 -- 避免多消费者循环消费同一个节点  while(this.head.get() >= this.tail.get());int chead = this.head.getAndIncrement();while(this.queue[this.getHead(chead)] == EMPTY); // 自旋  t = this.queue[this.getHead(chead)];this.queue[this.getHead(chead)] = EMPTY;return t;}public int getHead(int index){return index & (this.length - 1);}public int getTail(int index) {return index & (this.length - 1);}public int getHead() {return head.get() & (this.length - 1);}public int getTail() {return tail.get() & (this.length - 1);}public T[] getQueue() {return queue;}public int getLength() {return length;}public void setLength(int length) {this.length = length;}}

转载于:https://www.cnblogs.com/zemliu/p/3823597.html

ArrayBlockingQueue, LinkedBlockingQueue, ConcurrentLinkedQueue, RingBuffer相关推荐

  1. Java并发知识点快速复习手册(上)

    前言 本文快速回顾了常考的的知识点,用作面试复习,事半功倍. 面试知识点复习手册 已发布知识点复习手册 Java基础知识点面试手册 快速梳理23种常用的设计模式 Redis基础知识点面试手册 Java ...

  2. Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

    1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...

  3. 浅谈Disruptor

    Disruptor是一个低延迟(low-latency),高吞吐量(high-throughput)的事件发布订阅框架.通过Disruptor,可以在一个JVM中发布事件,和订阅事件.相对于Java中 ...

  4. Java中的5大队列,你知道几个?

    作者 | 王磊 来源 | Java中文社群(ID:javacn666) 通过前面文章的学习<一文详解「队列」,手撸队列的3种方法!>我们知道了队列(Queue)是先进先出(FIFO)的,并 ...

  5. 海量数据处理:从并发编程到分布式系统

    来自:DBAplus社群 作者介绍 Mark,一个正在成长的小码农. 本系列文章主要围绕高并发这一话题展开,分享笔者在并发处理上的学习思路以及踩过的坑.具体思路大体分为三部分: Java多线程编程: ...

  6. 【金三银四】java多线程并发编程pdf

    线程 线程的启动 实现Runnab1e接口 继承Thread类 实现Callable接口 线程的状态 线程的方法 线程的优先级 守护线程 未捕获异常处理器 并发编程的问题 线程引入开销:上下文切换与内 ...

  7. java add offer_图解Java中的5大队列!(干货收藏)

    Java 中的队列有很多,例如:ArrayBlockingQueue.LinkedBlockingQueue.PriorityQueue.DelayQueue.SynchronousQueue等,那它 ...

  8. SpringBoot开发案例从0到1构建分布式秒杀系统

    前言 最近,被推送了不少秒杀架构的文章,忙里偷闲自己也总结了一下互联网平台秒杀架构设计,当然也借鉴了不少同学的思路.俗话说,脱离案例讲架构都是耍流氓,最终使用SpringBoot模拟实现了部分秒杀场景 ...

  9. 陆金所 CAT 优化实践

    1 背景 CAT 介绍 CAT (Central Application Tracking)是一个实时监控系统,由美团点评开发并开源,定位于后端应用监控.应用集成客户端的方式上报中间件和业务数据,支持 ...

最新文章

  1. 使用 Inception-v3,实现图像识别(Python、C++)
  2. NeurIPS TAPE | 用于评估蛋白质表示学习性能的多任务平台
  3. 什么是微服务架构,该从哪些方面深入理解?
  4. Python-OpenCV学习--USB摄像头读取图像上下翻转
  5. 【机器学习基础】(五):通俗易懂决策树与随机森林及代码实践
  6. HDU 1260 Tickets
  7. java获取当前运行代码的类名、方法名、行号
  8. 中国风吉祥纹样底纹背景,艾草绿和天青色趋势色彩
  9. 在DataWorks中实现指定UDF只能被指定账户访问
  10. mysql遇见 column count of mysql.proc is wrong expected 20 found16
  11. oracle 11g regexp_substr,oracle中REGEXP_SUBSTR方法的使用
  12. spring的前后台数据传输。
  13. 使用IronPython集成Python和.NET
  14. idea显示左边project栏和隐藏project栏的快捷键
  15. 工程测量计算机在线用,工程测量中的计算机编程新技术.doc
  16. 【转】js高德地图图标合集
  17. 自动写故事、写字成图?5款有趣实用的AIGC工具分享
  18. 下载网页上的视频—Flash Video Downloader插件
  19. 在WIN7正常使用老版本工商银行华虹U盾驱动解决办法
  20. 索罗斯:国际银行家的金融黑客

热门文章

  1. 东北天到ecef的变换_GNSS学习笔记-坐标转换
  2. 电脑故障维修:新手必看的修电脑技巧!
  3. Linux文件默认权限和umask笔记
  4. c语言不循环链表,无头单向不循环链表相关接口实现(C语言)
  5. mysql003操作表DDL
  6. 未来ui设计的发展趋势_2025年的未来UI趋势?
  7. 2021 年 JavaScript 大事记
  8. IDEA 实用功能Auto Import:自动优化导包(自动删除、导入包)
  9. 对AI"出错"零容忍?美国加强AI推理解释能力研究
  10. C#实现写入文本文件内容功能