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


简介

本篇讲解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(Runnable task);
// 有返回值异步
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,支持链式回调、多任务组合、异常统一处理
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐