目录

Java 队列概述

BlockingQueue 阻塞队列

LinkedList 双链表队列

ArrayDeque 双向数组队列

ConcurrentLinkedQueue 并发安全队列

无界延时阻塞队列 DelayQueue


Java 队列概述

1、Queue 队列接口是一种 Collection, 被设计用于处理之前临时保存在某处的元素。除了基本的 Collection 操作之外队列还提供了额外的插入、提取和检查操作。每一种操作都有两种形式:如果操作失败则抛出一个异常;如果操作失败则返回一个特殊值(null或 false,取决于是什么操作)。

2、队列通常是以 FIFO(先进先出)的方式排序元素,但是这不是必须的。

3、只有优先级队列可以根据提供的比较器对元素进行排序或者是采用正常的排序。无论怎么排序队列的头将通过调用 remove() 或 poll() 方法进行移除。

4、在 FIFO 队列种,所有新的元素被插入到队尾,其他种类的队列可能使用不同的布局来存放元素。

5、每个 Queue 必须指定排序属性。

Queue 接口继承 Collection 接口,Collection 接口继承 Iterable 接口
BlockingQueue 接口、Deque接口继承 Queue 接口
AbstractQueue 抽象类实现Queue接口
BlockingDeque 接口、TransferQueue接口继承 BlockingQueue 接口
BlockingDeque 接口继承 Deque 接口
LinkedBlockingDeque 类实现 BlockingDeque 接口
LinkedTransferQueue 类接口实现 TransferQueue 接口
Linkedlist 类、ArrayDeque 类、ConcurrentLinkedDeque 类实现了Deque 接口
ArrayBlockingQueue 类、LinkendBlockingQueue 类、LinkedBlockingDeque 类、LinkedT ransferQueue 类、SynchronousQueue 类、PriorityBlockQueue 类、DelayQueue 类继承了AbstractQueue 抽象类和实现了 BlockingQueue接口
PriorityQueue 类和 ConcurrentLinkedQueue 类继承了 AbstractQueue 抽象类

BlockingQueue 阻塞队列

1、java.util.concurrent.BlockingQueue 阻塞队列是 JDK 1.5 新增的接口,它提供了不同功能的 7 个实现类(JDK7),也就是提供了 7 个不同的阻塞队列。

2、BlockingQueue 提供了线程安全的队列访问方式,是一个支持两个附加操作的队列,在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。

3、java.util.concurrent 并发包下很多高级同步类的实现都是基于 BlockingQueue 。

4、BlockingQueue 不接受 null 元素,试图 add、put 或 offer 一个 null 元素时,某些实现会抛出 NullPointerException,null 被用作指示 poll 操作失败的警戒值。

5、BlockingQueue 阻塞队列可以是限定容量的,也可以没有容量约束时,如 LinkedBlockingDeque<E>、LinkedBlockingQueue<E> 队列默认大小为 Integer.MAX_VALUE。

6、BlockingQueue 典型应用就是生产者-消费者使用场景,如 socket 客户端数据的读取和解析,读取数据的线程不断将数据放入队列,然后解析线程不断从队列取数据解析。可以安全地与多个生产者和多个使用者一起使用。

7、BlockingQueue 接口是 Queue 的子接口,它的主要用途并不是作为容器,而是作为线程同步的的工具,因此他具有一个很明显的特性,当生产者线程试图向 BlockingQueue 放入元素时,如果队列已满,则线程被阻塞,当消费者线程试图从中取出一个元素时,如果队列为空,则该线程会被阻塞,正是因为它所具有这个特性,所以在程序中多个线程交替向 BlockingQueue 中放入元素,取出元素,它可以很好的控制线程之间的通信。

四种操作形式

1、对于不能立即满足但可能在将来某一时刻可以满足的操作,BlockingQueue 提供了四组不同的方法,如下表所示:

操作 抛出异常 特殊值 阻塞 超时
插入 add(e) offer(e) put(e) offer(e, time, unit)
移除 remove() poll() take() poll(time, unit)
检查 element() peek() 不可用 不可用

抛出异常:如果试图的操作无法立即执行,抛出异常
特殊值:如果试图的操作无法立即执行,返回一个特定的值(true / false /null取决于具体操作)。
阻塞:如果试图的操作无法立即执行,该方法调用将会无限期阻塞,直到条件满足后再继续执行
超时:如果试图的操作无法立即执行,该方法调用将会在指定时间内阻塞,直到条件满足后再继续执行或者超时后抛出异常

2、实际项目应该因地制宜的选择不同的方法进行使用

7 个阻塞队列

1、java.util.concurrent.BlockingQueue 阻塞队列提供了不同功能的 7 个实现类(JDK7),也就是提供了 7 个不同的阻塞队列。

ArrayBlockingQueue      一个由数组结构组成的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序,新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。 这是一个典型的“有界缓存区”,一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。
LinkedBlockingQueue     一个由链表结构组成的有界阻塞队列。此队列按 FIFO(先进先出)排序元素。新元素插入到队列的尾部,并且队列获取操作会获得位于队列头部的元素。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。 
可选的容量范围构造方法参数作为防止队列过度扩展的一种方法。如果未指定容量,则它等于 Integer.MAX_VALUE。除非插入节点会使队列超出容量,否则每次插入后会动态地创建链接节点。 
PriorityBlockingQueue     一个支持优先级排序的无界阻塞队列。此类不允许使用 null 元素。依赖自然顺序的优先级队列也不允许插入不可比较的对象。
DelayQueue     一个使用优先级队列实现的无界阻塞队列。只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且 poll 将返回 null。此队列不允许使用 null 元素。 
SynchronousQueue     一个不存储元素的阻塞队列。其中每个插入操作必须等待另一个线程的对应移除操作 ,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有。
它非常适合于传递性设计,在这种设计中,在一个线程中运行的对象要将某些信息、事件或任务传递给在另一个线程中运行的对象,它就必须与该对象同步。
LinkedTransferQueue     一个由链表结构组成的无界阻塞队列。这个队列相对于任何给定的生产者订购元素FIFO(先进先出)。 队列的头部是那些已经排队的元素是一些生产者的最长时间。 队列的尾部是那些已经在队列上的元素是一些生产者的最短时间。 
LinkedBlockingDeque     一个由链表结构组成的双向阻塞队列。可选的容量范围构造方法参数是一种防止过度膨胀的方式。如果未指定容量,那么容量将等于 Integer.MAX_VALUE。只要插入元素不会使双端队列超出容量,每次插入后都将动态地创建链接节点。 

2、实际开发中应该以实际需求合理的选择适合的阻塞队列。

在线代码演示:https://gitee.com/wangmx1993/java-se/blob/master/src/main/java/org/example/queue/blockingQueue

LinkedList 双链表队列

1、LinkedList 实现了 List 和 Deque 接口,所以是一种双链表结构,可以当作堆栈、队列、双向队列使用。

2、一个双向列表的每一个元素都有三个整数值:元素、向后的节点链接、向前的节点链接。

3、LinkedList 的增加和删除效率相对较高,而查找和修改的效率相对 ArrayLis 较低。

4、以下情况建议使用 ArrayList:频繁访问列表中的一个元素;只在列表的首尾添加元素。

5、以下情况建议使用 LinkedList:频繁地在列表开头、中间、末尾添加和删除元素;需要通过循环迭代来访问列表中的元素。

6、LinkedList不是线程安全的,所以可以使用如下方式保证线程安全:List list = Collections.synchronizedList(new LinkedList<>());

在线演示源码:https://gitee.com/wangmx1993/java-se/blob/master/src/main/java/org/example/queue/LinkedListTest.java

ArrayDeque 双向数组队列

1、由数组组成的双端队列,实现了 Deque  接口 ‑ 可用于双端队列 。

2、没有容量限制,根据需要扩容。

3、不是线程安全的,禁止插入null元素。

4、当用作栈时,比栈速度快,当用作队列时,速度比LinkList快。

5、大部分方法的算法时间复杂度为O(1)。

6、remove、removeFirstOccurrence、removeLastOccurrence、contains、remove 和批量操作的
算法时间复杂度O(n)

在线源码:https://gitee.com/wangmx1993/java-se/blob/master/src/main/java/org/example/queue/ArrayDequeTest.java

ConcurrentLinkedQueue 并发安全队列

1、ConcurrentLinkedQueue 使用的是 CAS 原语无锁队列实现,是一个异步队列,入队的速度很快,出队进行了加锁。

2、ConcurrentLinked 是由链表结构组成的线程安全的先进先出无界队列。

3、当多线程要共享访问集合时,ConcurrentLinkedQueue 是一个比较好的选择 。

4、不允许插入 null 元素,支持非阻塞地访问并发安全的队列,不会抛出 ConcurrentModifiationException 异常。

5、size 方法不是准确的,因为在统计集合的时候,队列可能正在添加元素,导致统计不准。

6、批量操作 addAll、removeAll、retainAll、containsAll、equals 和 toArray 不保证原子性(操作不可分割)

在线演示源码:https://gitee.com/wangmx1993/java-se/blob/master/src/main/java/org/example/queue/ConcurrentLinkedQueueTest.java

无界延时阻塞队列 DelayQueue

1、DelayQueue = Delayed + BlockingQueue,队列中的元素必须实现 Delayed 接口,实现 getDelay 方法。

2、如下所示源码 take 方法获取元素时需要等待延时时间过了才能获取到元素,即只有当 getDelay 方法值小于等于0时才能拿到元素。

3、应用场景:

缓存系统的设计:可以用 DelayQueue 保存缓存元素的有效期,然后用一个线程循环的查询 DelayQueue 队列,一旦能从 DelayQueue 中获取元素时,表示缓存有效期到了。

定时任务调度:使用 DelayQueue 队列保存当天将会执行的任务和执行时间,一旦从 DelayQueue 中获取到任务就开始执行。

4、注意事项:

(1)服务器重启后,数据全部消失,怕宕机。
(2)集群扩展相当麻烦
(3)因为内存条件限制的原因,比如下单未付款的订单数太多,那么很容易就出现OOM异常

在线演示源码:

https://gitee.com/wangmx1993/java-se/src/main/java/org/example/queue/delayQueue

Java 队列 Queue 使用说明相关推荐

  1. Java队列 Queue

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/120828046 本文出自[赵彦军的博客] Java队列 Queue Java队列 ...

  2. java lifo 队列_1.8 Java 队列 Queue、双端队列 Deque - Java 知识总结与学习

    queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口.除了基本的 Collection 操作外,队列还 ...

  3. Java队列Queue

    队列Queue是一个先进先出的数据结构:与list.set同一级别,继承了collection接口. Queue的实现 阻塞队列(BolckingQueue) 非阻塞队列 阻塞队列(BolckingQ ...

  4. java队列——queue详细分析

    Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构 Queue接口与List.Set同一级别,都是继承了Collection接口.LinkedList实现了Deque接 口.   Q ...

  5. java队列queue的我觉得很好的使用方式

    LinkedList实现了queue接口,通常使用LinkedList 其中关键两个函数:offer().poll() offer()表示"排队"----插入到队列最前,poll( ...

  6. Java队列Queue的使用

    首先我们需要知道使用队列是什么,以及使用队列的意义. 一个队列基本上可以认为是一个先入先出(FIFO)的数据结构,队列和数组的主要区别就在于,我们在使用数组时,必须在前面就定义好数组的长度,这就有了很 ...

  7. Java队列Queue使用详解(*)

    Queue是java中实现队列的接口,它总共只有6个方法,我们一般只用其中3个就可以了.Queue的实现类有LinkedList和PriorityQueue.最常用的实现类是LinkedList. Q ...

  8. 【Java】Java队列Queue使用详解

    Deque是一个双端队列接口(double ended queue),继承自Queue接口,Deque的实现类是LinkedList.ArrayDeque.LinkedBlockingDeque,其中 ...

  9. java队列(Queue)用法总结

    项目github地址:bitcarmanlee easy-algorithm-interview-and-practice 欢迎大家star,留言,一起学习进步 1.队列的特点 队列是一种比较特殊的线 ...

  10. 中高级工程师Java开发!java队列queue实现

    主要内容 本文是从大型互联网系统的应用角度探讨分布式缓存的.本文站在原理.框架.架构.案例等多个视角对分布式缓存进行了探讨. 互联网系统随着容量需求的陡增,许多看似简单的存储类场景都面临着巨大的容量问 ...

最新文章

  1. python解析任意json
  2. 完美解决Linux服务器tomcat开机自启动问题
  3. Oracle Dataguard之Real-Time Apply
  4. 001_Servlet简介
  5. 如何设置Reporting Services链接到网页URL的参数?
  6. kubesphere发布应用到应用商店完整步骤
  7. Android开发之Handler机制记录
  8. java空值转datetime,解决Java (Spring boot) 读取数据库字段,datetime 格式为null,抛出异常 Zero date value prohibited...
  9. android图标错误的是什么意思啊,Android错误:找不到与给定名称匹配的资源(在icon处,值为@drawable/icon) - Android - srcmini...
  10. mac bochs 调试linux,Mac OS X下编译安装带debugger的bochs
  11. 在矩池云上使用A6000/3090跑ikatago说明
  12. ubuntu 部署 redis 主从节点配置
  13. 支付宝调起,应用签名失败,请联系商家
  14. python 录制网易云登陆_Python爬虫教程,爬取网易云的音乐
  15. java cmd 乱码_java在cmd运行时出现乱码解决方法
  16. 数学科普书籍介绍(一)
  17. 西南科技大学城市学院计算机专业录取分数线,西南科技大学城市学院2020年录取分数线(附2017-2020年分数线)...
  18. html中footer怎么写,HTML DOM Footer用法及代码示例
  19. Android设置RecyclerView的Header和Footer
  20. 41家对中国市场依赖度最高(依营收占比计算)的美国公司

热门文章

  1. [导入]QZONE跳转FLASH地址生成工具
  2. was如何使用gzip_一文详解前端Node原生模块zlib,开启gzip压缩让页面响应速度更快...
  3. 拓端tecdat|Nelsen-Siegel—Svensson扩展模型简介
  4. java json 图片_图片路径存储且item的json化
  5. java接口自动化框架_java接口自动化测试框架及断言详解
  6. python实现仿射变换
  7. Pytorch和Torchvision版本对应
  8. 神经网络入门之RNN(三)
  9. android.mk 编译选项,Android.mk中加入选项,编译生成可以直接安装的apk包
  10. h5 如何录音保存上传_H5录音及保存到后台recorder.js实现