当前位置: 首页 > backend >正文

Java中单向队列的多种实现类详解

Java中单向队列多种实现类详解:单线程与多线程全景式解析

    • 前言
    • 一、队列的基本接口
    • 二、单线程队列实现类
      • 2.1 LinkedList
        • 2.1.1 简介
        • 2.1.2 常用方法
        • 2.1.3 优缺点
        • 2.1.4 适用范围
      • 2.2 ArrayDeque
        • 2.2.1 简介
        • 2.2.2 常用方法
        • 2.2.3 优缺点
        • 2.2.4 适用范围
      • 2.3 PriorityQueue
        • 2.3.1 简介
        • 2.3.2 常用方法
        • 2.3.3 优缺点
        • 2.3.4 适用范围
    • 三、多线程并发队列实现类
      • 3.1 ConcurrentLinkedQueue
        • 3.1.1 简介
        • 3.1.2 常用方法
        • 3.1.3 优缺点
        • 3.1.4 适用范围
      • 3.2 ArrayBlockingQueue
        • 3.2.1 简介
        • 3.2.2 常用方法
        • 3.2.3 优缺点
        • 3.2.4 适用范围
      • 3.3 LinkedBlockingQueue
        • 3.3.1 简介
        • 3.3.2 常用方法
        • 3.3.3 优缺点
        • 3.3.4 适用范围
      • 3.4 PriorityBlockingQueue
        • 3.4.1 简介
        • 3.4.2 常用方法
        • 3.4.3 优缺点
        • 3.4.4 适用范围
      • 3.5 DelayQueue
        • 3.5.1 简介
        • 3.5.2 常用方法
        • 3.5.3 优缺点
        • 3.5.4 适用范围
      • 3.6 SynchronousQueue
        • 3.6.1 简介
        • 3.6.2 常用方法
        • 3.6.3 优缺点
        • 3.6.4 适用范围
    • 四、队列实现类对比总结
    • 五、最佳实践与选择建议

前言

队列(Queue)作为一种常用的数据结构,在Java开发中,无论日常业务开发还是算法题、并发编程,队列都有着广泛应用。Java标准库为我们提供了丰富的队列实现类,既有适合单线程场景的高性能实现,也有专为多线程并发设计的线程安全队列。本文我将系统梳理Java中单向队列的实现类,详细分析它们的用法、方法、优缺点及适用场景,帮你在实际开发中游刃有余地选择合适的队列。如果想了解双端队列的实现类和用法,请进我主页搜索查看下一篇双端队列的实现类和用法专题。


一、队列的基本接口

Java中队列的核心接口是java.util.Queue,它定义了队列的基本操作:

  • offer(E e):入队,添加元素,返回是否成功。
  • poll():出队,移除并返回队首元素,队列为空时返回null
  • peek():查看队首元素但不移除,队列为空时返回null

此外,Deque(双端队列)接口扩展了队列的功能,支持两端插入和删除。


二、单线程队列实现类

2.1 LinkedList

2.1.1 简介

LinkedList实现了QueueDeque接口,底层是双向链表。它既可以作为队列,也可以作为栈和双端队列使用。

2.1.2 常用方法
Queue<Integer> queue = new LinkedList<>();
queue.offer(1);         // 入队
queue.offer(2);
System.out.println(queue.poll()); // 1,出队
System.out.println(queue.peek()); // 2,查看队首
System.out.println(queue.isEmpty()); // false
2.1.3 优缺点
  • 优点
    • 支持队列、栈、双端队列等多种用法,灵活性高。
    • 插入和删除操作效率高(O(1))。
  • 缺点
    • 不是线程安全的。
    • 每个节点有额外的指针开销,内存占用较大。
    • 随机访问性能差(O(n))。
2.1.4 适用范围
  • 适合单线程环境下,频繁插入和删除的场景。
  • 需要双端队列或栈功能时也可选用。

2.2 ArrayDeque

2.2.1 简介

ArrayDeque实现了QueueDeque接口,底层是循环数组。它是Java官方推荐的队列和栈实现。

2.2.2 常用方法
Queue<Integer> queue = new ArrayDeque<>();
queue.offer(1);
queue.offer(2);
System.out.println(queue.poll()); // 1
System.out.println(queue.peek()); // 2
System.out.println(queue.isEmpty()); // false
2.2.3 优缺点
  • 优点
    • 基于数组,内存利用率高,性能优于LinkedList
    • 支持队列和栈操作,API丰富。
    • 没有同步开销,单线程下性能最好。
  • 缺点
    • 不是线程安全的。
    • 不能存储null元素。
    • 扩容时有一定性能开销。
2.2.4 适用范围
  • 单线程环境下,推荐作为队列或栈的实现。
  • 需要高性能、低内存开销的场景。

2.3 PriorityQueue

2.3.1 简介

PriorityQueue实现了Queue接口,底层是最小堆(优先队列)。元素出队顺序由优先级决定。

2.3.2 常用方法
Queue<Integer> queue = new PriorityQueue<>();
queue.offer(3);
queue.offer(1);
queue.offer(2);
System.out.println(queue.poll()); // 1
System.out.println(queue.peek()); // 2
2.3.3 优缺点
  • 优点
    • 支持优先级队列,元素自动排序。
    • 插入和删除的时间复杂度为O(log n)。
  • 缺点
    • 不是线程安全的。
    • 不能存储null元素。
    • 只保证队首元素有序,遍历时无序。
2.3.4 适用范围
  • 需要优先级调度、任务排序等场景。
  • 单线程环境下的优先级队列。

三、多线程并发队列实现类

3.1 ConcurrentLinkedQueue

3.1.1 简介

ConcurrentLinkedQueue是基于链表的无界线程安全队列,采用CAS算法实现高并发。

3.1.2 常用方法
Queue<Integer> queue = new ConcurrentLinkedQueue<>();
queue.offer(1);
queue.offer(2);
System.out.println(queue.poll()); // 1
System.out.println(queue.peek()); // 2
3.1.3 优缺点
  • 优点
    • 线程安全,无需加锁,适合高并发场景。
    • 无界队列,容量只受内存限制。
  • 缺点
    • 不支持阻塞操作。
    • 不能存储null元素。
3.1.4 适用范围
  • 多线程环境下的高并发队列。
  • 适合任务分发、消息队列等场景。

3.2 ArrayBlockingQueue

3.2.1 简介

ArrayBlockingQueue是基于数组的有界阻塞队列,支持阻塞的入队和出队操作。

3.2.2 常用方法
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(2);
queue.put(1); // 阻塞式入队
queue.put(2);
System.out.println(queue.take()); // 1,阻塞式出队
System.out.println(queue.peek()); // 2
3.2.3 优缺点
  • 优点
    • 线程安全,支持阻塞操作。
    • 有界队列,防止内存溢出。
  • 缺点
    • 容量固定,需提前指定。
    • 扩容不方便。
3.2.4 适用范围
  • 生产者-消费者模式。
  • 需要容量限制的多线程队列。

3.3 LinkedBlockingQueue

3.3.1 简介

LinkedBlockingQueue是基于链表的可选有界阻塞队列,默认容量为Integer.MAX_VALUE

3.3.2 常用方法
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
queue.put(1);
queue.put(2);
System.out.println(queue.take()); // 1
System.out.println(queue.peek()); // 2
3.3.3 优缺点
  • 优点
    • 线程安全,支持阻塞操作。
    • 可选有界,灵活性高。
    • 插入和删除操作效率高。
  • 缺点
    • 内存占用比数组实现高。
    • 默认无界,需注意内存溢出风险。
3.3.4 适用范围
  • 生产者-消费者模式。
  • 任务调度、线程池等场景。

3.4 PriorityBlockingQueue

3.4.1 简介

PriorityBlockingQueue是支持优先级的线程安全无界阻塞队列。

3.4.2 常用方法
BlockingQueue<Integer> queue = new PriorityBlockingQueue<>();
queue.put(3);
queue.put(1);
queue.put(2);
System.out.println(queue.take()); // 1
System.out.println(queue.peek()); // 2
3.4.3 优缺点
  • 优点
    • 线程安全,支持优先级队列。
    • 无界队列,容量只受内存限制。
  • 缺点
    • 不保证元素的遍历顺序。
    • 不能存储null元素。
3.4.4 适用范围
  • 多线程环境下的优先级任务调度。
  • 定时任务、调度中心等场景。

3.5 DelayQueue

3.5.1 简介

DelayQueue是支持延迟出队的线程安全无界阻塞队列,元素只有到期后才能被取出。

3.5.2 常用方法
class MyTask implements Delayed {private long time;public MyTask(long delay) { this.time = System.currentTimeMillis() + delay; }public long getDelay(TimeUnit unit) { return unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS); }public int compareTo(Delayed o) { return Long.compare(this.time, ((MyTask)o).time); }
}DelayQueue<MyTask> queue = new DelayQueue<>();
queue.put(new MyTask(1000)); // 1秒后可取出
System.out.println(queue.take()); // 阻塞直到到期
3.5.3 优缺点
  • 优点
    • 线程安全,支持延迟队列。
    • 适合定时任务、缓存等场景。
  • 缺点
    • 只能存储实现Delayed接口的元素。
    • 无界队列,需注意内存溢出。
3.5.4 适用范围
  • 定时任务调度、延迟消息等场景。

3.6 SynchronousQueue

3.6.1 简介

SynchronousQueue是一个不存储元素的阻塞队列,每个插入操作必须等待另一个线程的移除操作。

3.6.2 常用方法
BlockingQueue<Integer> queue = new SynchronousQueue<>();
new Thread(() -> {try { queue.put(1); } catch (InterruptedException e) {}
}).start();
System.out.println(queue.take()); // 1
3.6.3 优缺点
  • 优点
    • 线程安全,适合线程间直接传递数据。
  • 缺点
    • 不存储元素,不能缓存数据。
3.6.4 适用范围
  • 线程池、任务直接交付等场景。

四、队列实现类对比总结

类名线程安全是否阻塞是否有界是否支持优先级适用场景
LinkedList单线程队列/栈/双端队列
ArrayDeque单线程高性能队列/栈
PriorityQueue单线程优先级队列
ConcurrentLinkedQueue高并发无界队列
ArrayBlockingQueue生产者-消费者,有界队列
LinkedBlockingQueue可选生产者-消费者,任务调度
PriorityBlockingQueue并发优先级队列
DelayQueue定时/延迟任务
SynchronousQueue线程间直接传递

五、最佳实践与选择建议

  • 单线程场景:优先选择ArrayDeque,如需双端操作可用LinkedList
  • 需要优先级:单线程用PriorityQueue,多线程用PriorityBlockingQueue
  • 高并发场景:用ConcurrentLinkedQueue(无阻塞),或BlockingQueue系列(阻塞)。
  • 生产者-消费者:推荐ArrayBlockingQueueLinkedBlockingQueue
  • 定时/延迟任务:用DelayQueue
  • 线程间直接传递:用SynchronousQueue

若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ

http://www.xdnf.cn/news/12936.html

相关文章:

  • 智警杯备赛--excel模块
  • CSS高级技巧及新增属性
  • LLMs 系列科普文(12)
  • 2025-06-02-IP 地址规划及案例分析
  • SDC命令详解:使用set_max_area命令进行约束
  • DiMTAIC 2024 数字医学技术及应用创新大赛-甲状腺B超静态及动态影像算法赛-参赛项目
  • 一文掌握 Tombola 抽象基类的自动化子类测试策略
  • LMDeploy 课程
  • ubuntu下编译osg3.6.5源码
  • CSP信奥赛C++常用系统函数汇总
  • 异或和之差-字典树
  • 二分查找 -P1102 A-B 数对
  • 风力发电机领域的声纹监测产品
  • 循环神经网络(RNN):从理论到翻译
  • 【Elasticsearch】映射:详解 _source store 字段
  • 基于机器学习的智能故障预测系统:构建与优化
  • 基于算法竞赛的c++编程(22)二进制,十进制,16进制
  • 面向对象之 继承中的成员访问特点
  • split方法
  • mybatis执行insert如何返回id
  • 开疆智能Ethernet/IP转Modbus网关连接斯巴拓压力传感器配置案例
  • LeetCode 高频 SQL 50 题(基础版)之 【高级字符串函数 / 正则表达式 / 子句】· 上
  • MCP(Model Context Protocol)与提示词撰写
  • unipp---HarmonyOS 应用开发实战
  • 并发和并行
  • 相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
  • 例说局部性原理给程序带来的提升
  • 2480: 2020年06月2级T1:计算矩阵边缘元素之和
  • 计数思想-众数
  • vmware 设置 dns