【JUC】阻塞队列|DelayQueue延时原理|CompletableFuture异步API大全
2026/6/12 13:01:56 网站建设 项目流程

大家好,我是程序员二叉。


简介

本篇讲解BlockingQueue阻塞队列核心作用、四大常用队列差异与场景、DelayQueue底层延时实现、CompletableFuture全套高频异步API,生产环境高频工具类面试必背。欢迎点赞关注收藏。


一、BlockingQueue 阻塞队列核心作用

  1. 线程安全容器:自带锁机制,多线程并发put/take无竞态异常
  2. 双向阻塞能力
    • 队列已满:生产者调用put()阻塞等待空位
    • 队列为空:消费者调用take()阻塞等待元素
  3. 解耦生产者-消费者模型,削峰填谷,平衡上下游线程执行速度
  4. 自带批量操作、超时存取、非阻塞存取多种API适配不同业务

二、四大主流阻塞队列区别&适用场景

1. ArrayBlockingQueue

  • 底层:有界固定数组,初始化必须指定容量
  • 锁机制:全局一把ReentrantLock,读写操作互斥不能并行
  • 适用:流量可控、固定缓冲大小的同步生产消费场景

2. LinkedBlockingQueue

  • 底层:单向链表,默认无界,可传容量设为有界
  • 锁机制:生产者、消费者两把独立锁,读写可并行,吞吐量更高
  • 适用:高吞吐异步任务、ThreadPoolExecutor线程池默认工作队列

3. SynchronousQueue

  • 无存储缓冲区,不存放任何元素;put必须匹配一个take才交付
  • 支持公平/非公平模式,无容量限制
  • 适用:瞬时高并发、任务不排队,CachedThreadPool底层队列

4. DelayQueue

  • 无界优先阻塞队列,元素必须实现Delayed延时接口
  • 只有延时到期的元素才能被take取出
  • 适用:定时任务、订单超时关闭、会话过期、接口延迟重试

三、DelayQueue 底层完整原理

  1. 内部依托PriorityQueue优先队列,按照元素剩余延时时间升序排序,队首是最快到期任务
  2. 全局一把ReentrantLock,搭配一个Condition等待队列
  3. take()执行流程:
    1. 加锁取出队首延时任务
    2. 判断延时是否到期,到期直接取出返回
    3. 未到期则await阻塞等待,释放锁
    4. 新延时任务入队会唤醒阻塞线程,重新校验队首时间
  4. 业务元素实现Delayed接口,重写getDelay()返回剩余延时毫秒

四、CompletableFuture 高频常用API

1. 创建异步任务

// 无返回值异步CompletableFuture.runAsync(Runnabletask);// 有返回值异步CompletableFuture.supplyAsync(Supplier<T>task);

2. 完成回调(成功 / 失败都会执行)

whenComplete(BiConsumer<T, Throwable>)

3. 异常单独兜底处理

exceptionally(Function<Throwable,T>)异常时返回默认兜底结果

4. 串行链式执行

  • thenApply():接收上一步结果,转换返回新值
  • thenAccept():消费上一步结果,无返回值
  • thenRun():不接收结果,单纯执行后续任务

5. 多任务组合编排

  • thenCombine():两个任务全部完成,合并两者结果
  • applyToEither():两个任务谁先执行完,使用最先完成的结果
  • allOf():阻塞等待所有异步任务全部执行完毕
  • anyOf():任意一个任务完成就立刻结束等待

6. 阻塞获取结果

  • get():阻塞拿结果,抛出受检异常
  • get(long, TimeUnit):带超时阻塞获取
  • join():阻塞拿结果,只抛运行时异常,无需 try-catch 受检异常

面试速记总结

  1. 阻塞队列平衡生产消费;Array固定数组、Linked双锁高吞吐、Synchronous零缓冲
  2. DelayQueue基于优先队列排序延时任务,到期才可取出
  3. CompletableFuture替代原始Future,支持链式回调、多任务组合、异常统一处理

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询