一、ArrayBlockingQueue

首先看一段源码:

 public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {
private static final long serialVersionUID = -817911632652898426L;
final Object[] items;
int takeIndex;
int putIndex;
int count;
final ReentrantLock lock;
private final Condition notEmpty;
private final Condition notFull;
transient Itrs itrs = null;

ArrayBlockingQueue是一个数组队列,由代码看其维护了一个Object[] items数组,然后同步保证安全;

理解ArrayBlockingQueue主要理解两点即可:FIFO原则和同步安全访问。

①、既然是使用数组实现的队列,那么他如何保证队列的FIFO原则的呢?主要有三个序列控制:

  takeIndex(items index for next take, poll, peek or remove),即从队列中获取元素时的控制序列;

  putIndex(items index for next put, offer, or add),即往队列中增加元素的控制序列;

  count(Number of elements in the queue),即队列中的元素数量序列;

  takeIndex每移除一个元素takeIndex则+1(peek方法比较特殊,不会移除元素),当tokeIndex+1的值等于数组items长度时,takeIndex置0。

  putIndex每增加一个元素+1,当putIndex+1的值等于数组items的长度时,putIndex置0.

  count每增加一个元素+1,count每移除一个元素-1.

  由此可见,数组基于这三个变量的循环控制,实现了队列的FIFO。= =、

②、并发安全是基于ReentrantLock和两个Condition实现的。

  看一下构造方法:

 public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}

  使用单参构造时这个fair参数默认是false,即非公平锁。基于ReentrantLock和两个Condition的阻塞和唤醒实现同步;notEmpty在队列中没有元素可获取时阻塞线程,notFull在满队列不可插入时阻塞线程。

二、LinkedBlockingQueue

还是先看段源码:

 public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
private static final long serialVersionUID = -6903933977591709194L; static class Node<E> {
E item;
Node<E> next; Node(E x) { item = x; }
} private final int capacity; private final AtomicInteger count = new AtomicInteger(); transient Node<E> head; private transient Node<E> last; private final ReentrantLock takeLock = new ReentrantLock(); private final Condition notEmpty = takeLock.newCondition(); private final ReentrantLock putLock = new ReentrantLock(); private final Condition notFull = putLock.newCondition();

LinkedBlockingQueue和ArrayBlockingQueue有很多相似的地方,主要区别如下:

  ①LinkedBlockingQueue使用的是单向链表,而ArrayBlockingQueue使用的是数组,故LinkedBlockingQueue使用head节点和last节点维护FIFO原则。

  ②LinkedBlockingQueue分别使用了takeLock和putLock两个锁进行新增和移除元素的操作,这也导致了元素计数器count属性需要声明为AtomicInteger进行原子操作。

  ③LinkedBlockingQueue默认可以不指定队列大小,使用Integer.MAX_VALUE默认初始化队列大小。

三、PriorityBlockingQueue带有优先级的队列

看源码中属性部分:

public class PriorityBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
private static final long serialVersionUID = 5595510919245408276L; private static final int DEFAULT_INITIAL_CAPACITY = 11; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private transient Object[] queue; private transient int size; private transient Comparator<? super E> comparator; private final ReentrantLock lock; private final Condition notEmpty; private transient volatile int allocationSpinLock; private PriorityQueue<E> q;

其仍然是个数组,和ArrayBlockingQueue很像,也是通过单个lock加锁,其特点如下:

  ①、初始大小11,但是会自动扩容,最大可以到Integer.MAX_VALUE - 8;

  ②、其队列元素必须实现Comparator接口,以便其基于完全二叉树的最小堆和最大堆排序;

  ③、PriorityBlockingQueue本身不支持序列化,数组前加了transient修饰,其序列化会转化成PriorityQueue,反序列化时再转换成PriorityBlockingQueue自己。

  

java常用队列分析的更多相关文章

  1. 常用 Java 静态代码分析工具的分析与比较

    常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...

  2. JAVA常用数据结构及原理分析

    JAVA常用数据结构及原理分析 http://www.2cto.com/kf/201506/412305.html 前不久面试官让我说一下怎么理解java数据结构框架,之前也看过部分源码,balaba ...

  3. lesson2:java阻塞队列的demo及源码分析

    本文向大家展示了java阻塞队列的使用场景.源码分析及特定场景下的使用方式.java的阻塞队列是jdk1.5之后在并发包中提供的一组队列,主要的使用场景是在需要使用生产者消费者模式时,用户不必再通过多 ...

  4. Java 常用List集合使用场景分析

    Java 常用List集合使用场景分析 过年前的最后一篇,本章通过介绍ArrayList,LinkedList,Vector,CopyOnWriteArrayList 底层实现原理和四个集合的区别.让 ...

  5. (6)Java数据结构-- 转:JAVA常用数据结构及原理分析

    JAVA常用数据结构及原理分析  http://www.2cto.com/kf/201506/412305.html 前不久面试官让我说一下怎么理解java数据结构框架,之前也看过部分源码,balab ...

  6. Java应用常用性能分析工具

    Java应用常用性能分析工具 好的工具有能有效改善和提高工作效率或加速分析问题的进度,笔者将从事Java工作中常用的性能工具和大家分享下,如果感觉有用记得投一票哦,如果你有好的工具也可以分享给我 工具 ...

  7. 【转载】常用 Java 静态代码分析工具的分析与比较

    摘自:http://www.oschina.net/question/129540_23043常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基本概念及主要技术,随后 ...

  8. 细说并发5:Java 阻塞队列源码分析(下)

    上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...

  9. [转载] 常用 Java 静态代码分析工具的分析与比较

    转载自http://www.oschina.net/question/129540_23043 简介: 本文首先介绍了静态代码分析的基本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代 ...

随机推荐

  1. atitit.报表最佳实践oae 与报表引擎选型

    atitit.报表最佳实践oae 与报表引擎选型 1. 报表的主要的功能and结构 2 1.1. 查询设计器(配置化,metadata in html) ,anno 2 1.2. 查询引擎 2 1.3 ...

  2. 浅谈I2C总线

    I2C总线概述 I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备.I2C总线最主要的优点是其简单性和 ...

  3. EF操作VS中

    1.安装mysql server 2.安装MySql的VS插件(版本请下载最新版,百度自己搜索,这个不用多说)mysql-for-visualstudio-1.2.3.msi 3.安装用于.net连接 ...

  4. HDOJ 5289 Assignment 单调队列

    维护一个递增的和递减的单调队列 Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  5. PKI/CA

    PKI( Public Key Infrastructure )指的是公钥基础设施. CA ( Certificate Authority )指的是认证中心. PKI从技术上解决了网络通信安全的种种障 ...

  6. CSplashScene类

    #ifndef __TRANSITIONSCENE_H__ #define __TRANSITIONSCENE_H__ #include "GameFrameHead.h" cla ...

  7. android 批量上传图片

    额外还需要NetUtil和服务器端UpLoadPicture package com.example.girdviewtest; import java.util.ArrayList;import j ...

  8. 《C++ Primer》笔记-#include,#ifndef

    1.理解 #include 指示是怎样工作的 #include 设 施是 C++ 预处理器的一部分.预处理器处理程序的源代码,在编译器之前运行. C++ 继承了 C 的非常精细的预处理器.现在的 C+ ...

  9. docker Failed to get D-Bus connection 报错 docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash

    docker Failed to get D-Bus connection 报错 原创憬薇2016-01-15 11:25:26评论(10)40278人阅读   在centos7的容器里面出现了一个B ...

  10. jvm 调整tomcat的堆内存和常驻内存catalina.sh

    4.2 性能优化 tomcat性能取决于你的内存大小 上策:优化代码 中策:jvm优化机制  垃圾回收机制 把不需要的内存回收   优化jvm--优化垃圾回收策略 优化catalina.sh配置文件. ...