JUC包下定义了一个接口:BlockingQueue。其实现类有ArrayBlockingQueue等。本文先来介绍一下ArrayBlockingQueue。从字面可以看出,ArrayBlockingQueue是一种基于数组的阻塞队列,阻塞队列在线程池中会经常使用到。

首先来看看ArrayBlockingQueue的类图,如下所示。从类图可以看出,ArrayBlockingQueue继承自AbstractQueue,实现了BlockingQueue接口。

在ArrayBlockingQueue内部有一个数组items,同时定义了takeIndex和putIndex变量。由于是队列,因此一端入队操作,另一端进行出队操作。另外,内部定义了ReentrantLock作为独占锁。

1、构造函数

先来看看其构造函数。其有三给构造函数,不过都是调用这个构造函数。

构造函数的参数需要指定初始容量,同时指定采用公平锁还是非公平锁。从这一点可以看出,ArrayBlockingQueue是一个有界队列。

2、offer函数

offer操作用于向队列尾部插入一个元素,如果空闲则插入元素,如果非空闲,返回true。如果队列满,则返回false。下面让我们来看看offer操作的源码。

从上面的源码可以看出,不管插入成功与否,都会立即返回结果,因此这个方法是非阻塞的,但是也不能保证一定插入元素成功。

3、put函数

从源码中可以看出,put操作首先检查元素是否位空,如果为空,则抛异常。然后进行加锁,然后判断当前队列是否满了,如果满了就阻塞当前线程,然后挂起放入条件队列。当然,这个方式是相应中断的(因为上面lockInterruptibly方法可以响应中断)。如果队列没满,则入队。最后释放锁。

4、poll操作

poll是从队列头部取走元素,其源码如下:

首先进行加锁操作,然后判断当前队列元素是否为0,如果是返回空。否则返回队列头元素。这个方法是不支持响应中断的。至于deque操作,就是去数组中取元素,和普通队列处理逻辑没有区别。

5、take操作

take操作也是从队列头取元素。其源码如下所示:

从源码上可以看出,take也是支持响应中断的。如果队列元素为空,则会阻塞挂起,除非队列有元素被唤醒。也就是这个方法一定要保证取到元素,如果取不到元素,会等到有元素才返回。不像上面的poll方法,取不到就返回null。

6、peek操作

peek操作时查看队列首部的元素,但是不移除。源码如下:

从源码上可以看出,此方法也是非阻塞的。即使队列没有元素也就是会立即返回的(返回null)。不像上面的take操作,没有元素就等到有元素再返回。

7、size操作

此方法是获取队列元素个数的方法,源码如下:

从源码可以看出,size操作时加锁的,因为在定义count变量的时候没有使用volitate修饰,这样通过加锁保证了内存的可见性。这里其实也可以通过putIndex和takeIndex来得到队列元素长度。在Netty框架中的Bytebuf就是这样计算的。

java queue源码_Java高并发系列之ArrayBlockingQueue源码解析相关推荐

  1. shell 获取命令执行结果_java高并发系列 第31天:获取线程执行结果,这6种方法你都知道?...

    这是java高并发系列第31篇. 环境:jdk1.8. java高并发系列已经学了不少东西了,本篇文章,我们用前面学的知识来实现一个需求: 在一个线程中需要获取其他线程的执行结果,能想到几种方式?各有 ...

  2. java 检视_Java高并发系列——检视阅读(五)

    JUC中工具类CompletableFuture CompletableFuture是java8中新增的一个类,算是对Future的一种增强,用起来很方便,也是会经常用到的一个工具类,熟悉一下. Co ...

  3. java中acquire()_Java高并发系列之AQS中acquire源码解析

    我们知道,AQS中最重要的两个方法就是acquire和release方法.我们本文来走读走读acquire的源码. 首先,tryAcquire是需要子类具体去实现,其作用就是设置state的值,如果设 ...

  4. java 内存模型 多线程_Java 高并发三:Java内存模型和线程安全详解

    网上很多资料在描述Java内存模型的时候,都会介绍有一个主存,然后每个工作线程有自己的工作内存.数据在主存中会有一份,在工作内存中也有一份.工作内存和主存之间会有各种原子操作去进行同步. 下图来源于这 ...

  5. java service层 事务_Java高并发秒时啊API之Service层1

    ---2-1 使用Spring托管Service依赖理论---------------------------- spring ioc优势(工厂模式): 1.对象创建统一托管 2.规范的生命周期管理 ...

  6. [Java高并发系列(5)][详细]Java中线程池(1)--基本概念介绍

    1 Java中线程池概述 1.1 什么是线程池? 在一个应用当中, 我们往往需要多次使用线程, 这意味着我们需要多次创建和销毁线程.那么为什么不提供一个机制或概念来管理这些线程呢? 该创建的时候创建, ...

  7. Java高并发系列5-线程池

    Java高并发系列5-线程池 接上一篇Java并发系列4-并发容器我们继续 在编程中经常会使用线程来异步处理任务,但是每个线程的创建和销毁都需要一定的开销.如果每次执行一个任务都需要开个新线程去执行, ...

  8. java高并发系列 - 第3天:有关并行的两个重要定律

    java高并发系列第3篇文章,一个月,咱们一起啃下java高并发,欢迎留言打卡,一起坚持一个月,拿下java高并发. 有关为什么要使用并行程序的问题前面已经进行了简单的探讨.总的来说,最重要的应该是处 ...

  9. java高并发系列 - 第1天:必须知道的几个概念

    java高并发系列-第1天:必须知道的几个概念 同步(Synchronous)和异步(Asynchronous) 同步和异步通常来形容一次方法调用,同步方法调用一旦开始,调用者必须等到方法调用返回后, ...

最新文章

  1. l5如何通过路由走api版本回退查找设置
  2. 两篇文章说中断和异常之一
  3. java api中最常用的五个包_java 5 个常用的api包
  4. 格罗方德起诉台积电侵犯16项专利、影响巨大;中兴通讯与印尼Smartfren展开合作;网传FB开发新通讯应用Threads……...
  5. HTML/CSS基础知识总结
  6. java web 分页_Java Web(十一) 分页功能的实现
  7. Bailian4150 上机【DP】
  8. activity finish后没有destroy_Activity 基础知识点
  9. 小米6Android11刷机包,钉子户小米6的新生,换电池、背盖,升级android11
  10. ffmpeg将amr格式转成mp3格式
  11. 有些话很轻、很淡、很疼!+ 有些话,经典的让人想流泪
  12. 这个AR/VR设计原型利器,爆赞
  13. 百度账号找回服务器,百度网盘秒删的资源,用这工具一键找回
  14. Cortex-M4和M3处理器,究竟哪个市场更大?
  15. 生信常用分析图形绘制04 -- 桑基图
  16. 罗德里格斯公式Rodrigues' rotation formula推导
  17. 23种设计模式(一)
  18. 光圈叶片数量与衍射导致的品质和成像问题
  19. python c++情侣网名是什么意思_c++中嵌入python 看什么意思
  20. c语言找出4个整数中的最大值和最小值,如何用C语言的四个if语句从四个整数找到最大值和最小值...

热门文章

  1. python创建sqlite3数据库_树莓派使用 Python + SQLite 建立温度数据库
  2. 中科院等发布《2019研究前沿》
  3. Offer年薪低于25W全额退款|阿里、腾讯内推快艇《全链路大数据分析工程师》课程招生简章...
  4. 坚持早起21天,每月躺赚5000元!
  5. 23种设计模式之访问者模式
  6. Gvim开发环境配置笔记--Windows篇
  7. 从阿里核心场景看实时数仓的发展趋势
  8. 一文说清linux system load
  9. 技术干货 | 应用上线前的“体检”,你知道需要检测哪些指标吗?
  10. 阿里巴巴HRSSC:用宜搭实现业务管理模式创新