转自:https://blog.csdn.net/qq_23359777/article/details/70146778
1.介绍

ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection接口。底层以数组的形式保存数据(实际上可看作一个循环数组)。常用的操作包括 add ,offer,put,remove,poll,take,peek。

前三者add offer put 是插入的操作。后面四个方法是取出的操作。他们之间的区别和关联:

add: 内部实际上获取的offer方法,当Queue已经满了时,抛出一个异常。不会阻塞。

offer:当Queue已经满了时,返回false。不会阻塞。

put:当Queue已经满了时,会进入等待,只要不被中断,就会插入数据到队列中。会阻塞,可以响应中断。

取出方法中 remove和add相互对应。也就是说,调用remove方法时,假如对列为空,则抛出一场。另外的,poll与offer相互对应。take和put相互对应。peek方法比较特殊,前三个取出的方法,都会将元素从Queue的头部溢出,但是peek不会,实际上只是,获取队列头的元素。peek方法也不会阻塞。当队列为空时,直接返回Null。

2.对比LinkedBlockingQueue

LinkedBlockingQueue也是一个阻塞式的队列,与ArrayBlockingQueue的区别是什么呢?

LinkedBlockingQueue保存元素的是一个链表。其内部有一个Node的内部类,其中有一个成员变量 Node next。就这样形成了一个链表的结构,要获取下一个元素,只要调用next就可以了。而ArrayBlockingQueue则是一个数组。

LinkedBlockingQueue内部读写(插入获取)各有一个锁,而ArrayBlockingQueue则读写共享一个锁。

3.选择LinkedBlockingQueue还是ArrayBlockingQueue

个人感觉大多数场景适合使用LinkedBlockingQueue。在JDK源码当中有说明,LinkedBlockingQueue比ArrayBlockingQueue有更高的吞吐量,但是性能表现更难预测(也就是说相比ArrayBlockingQueue性能表现不稳定,但是也很稳定了)。

为什么会有吞吐量的区别,个人以为可能是ArrayBlockingQueue两个锁的缘故,在大量并发的情况下,插入和读取都很多时,就会造成一点的时间浪费。

还有一点,应为LinkedBlockingQueue创建时,默认会直接创建一个Integer.MAX_VALUE的数组,当插入少,读取多时,就会造成很大的空间浪费。而LinkedBlockingQueue实际上实在等需要的时候才会创建一个Node节点。

ArrayBlockingQueue详解的更多相关文章

  1. 20.并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解

    1. ArrayBlockingQueue简介 在多线程编程过程中,为了业务解耦和架构设计,经常会使用并发容器用于存储多线程间的共享数据,这样不仅可以保证线程安全,还可以简化各个线程操作.例如在“生产 ...

  2. java线程池的使用与详解

    java线程池的使用与详解 [转载]本文转载自两篇博文:  1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html   ...

  3. Java多线程学习之线程池源码详解

    0.使用线程池的必要性 在生产环境中,如果为每个任务分配一个线程,会造成许多问题: 线程生命周期的开销非常高.线程的创建和销毁都要付出代价.比如,线程的创建需要时间,延迟处理请求.如果请求的到达率非常 ...

  4. Java:多线程,线程池,ThreadPoolExecutor详解

    1. ThreadPoolExecutor的一个常用的构造方法 ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepA ...

  5. Java自带线程池和队列详解

    Java线程池使用说明 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后 ...

  6. Disruptor 详解 二

    Disruptor 的大名从很久以前就听说了,但是一直没有时间:看完以后才发现其内部的思想异常清晰,很容易就能前移到其他的项目,所以仔细了解一下还是很有必要的这.篇博客将主要从源码角度分析,Disru ...

  7. Java学习笔记 线程池使用及详解

    有点笨,参考了好几篇大佬们写的文章才整理出来的笔记.... 字面意思上解释,线程池就是装有线程的池,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程 ...

  8. 最强Java并发编程详解:知识点梳理,BAT面试题等

    本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...

  9. Java 并发编程 | 线程池详解

    原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...

随机推荐

  1. python在读取配置文件存入列表中,去掉回车符号

    self.receiver = map(lambda x: x.strip(), receiver_list) # 去掉list中的回车符号

  2. (转)Mysql数据库管理 表的维护

    原文:http://t.dbdao.com/archives/mysql%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AE%A1%E7%90%86-%E8%A1%A8%E7%9A%84 ...

  3. Python多线程&进程

    一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...

  4. Python数据类型(列表)

    文章内容参考了教程:http://www.runoob.com/python/python-basic-syntax.html#commentform Python 列表(List) 序列是Pytho ...

  5. ubuntu系统复制到其他地方或克隆后,如何正确修改IP及MAC地址的解决方案(图文详解)

    修改ip地址 永久修改MAC地址 方法一: 1)编辑“/etc/init.d/rc.local”文件(sudo gedit /etc/init.d/rc.local) 2)在此配置文件的最后面加上如( ...

  6. 006-动态生成验证码Servlet代码模板

    package checking; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java ...

  7. 遇到Caused by: java.lang.NoClassDefFoundError: javax/validation/ParameterNameProvider

    今天在做spring和hibernate整合的时候遇到这个问题 网上搜找到这里有解决办法 http://blog.csdn.net/jueshengtianya/article/details/122 ...

  8. 关于定位和z-index的一些小经历

    今天在工作过程中,遇到这么一个奇葩问题,搞了好一阵子才找到原因,遂总结了一下... 先上DEMO: <div style="width:800px; height:400px;&quo ...

  9. Messenger和MVVM中的View Services

    在前面的文章IoC容器和MVVM中, 介绍了IoC容器如何在大量用户类中帮助创建和分配用户类的实例.本文将介绍IoC容器如何帮助应用程序解耦,比如那些根据MVVM模式开发的应用.此模 式广泛应用在基于 ...

  10. PLC编程逻辑思路

    PLC编程逻辑思路 在整个执行过程的流程中,都是在不断地找启动条件,停止条件以及输出结果.当条件不够时,就得想办法如果添加标志位,根据已有条件去构造条件:当结果开发耦合时,就制造中间继电器去除耦合. ...