752 字
4 分钟
JUC 常用工具与异步结果:原子类、同步器、队列与 Future

不必逐个背 JUC 源码。先把原子更新、等待完成、控制并发、传递任务、组合结果对应到工具。

原子类与 LongAdder#

AtomicInteger 提供 incrementAndGet、compareAndSet 等原子操作,适合精确更新单个数值。多个独立原子操作不会自动组成事务。

LongAdder 在高争用时分散更新,减少单点竞争,适合统计指标。但并发期间 sum 不是统一锁定所有更新的原子快照,不能随意替代限额扣减和状态判断。

常见同步器#

工具用途边界
CountDownLatch等待若干任务或步骤完成计数到 0 后放行,不能重置同一个计数
CyclicBarrier多个参与方等待到达阶段点可重复使用,需处理超时和屏障破坏
Semaphore限制同时访问资源的数量获取后要正确释放,限制并发数而非每秒请求数

任务通常在 finally 中 countDown,避免异常路径遗漏计数。但计数归零不意味着全部成功,还要检查任务结果并设定等待超时。

BlockingQueue#

put 在容量不足时等待,take 在无元素时等待;offer/poll 支持立即返回或超时。ArrayBlockingQueue 使用固定容量;LinkedBlockingQueue 可指定容量,默认容量很大。

有界队列限制积压,连接生产者和消费者。但队列线程安全不保证业务处理成功,还要处理失败、关闭和重复任务。

Future 与 CompletableFuture#

Future 表示异步结果,get 可以阻塞等待,带超时形式限制等待;cancel(true) 尝试中断取消,不保证任务实际已停止。

CompletableFuture 支持组合异步步骤:

CompletableFuture<String> result = CompletableFuture
.supplyAsync(() -> loadName(), executor)
.thenApply(String::trim)
.exceptionally(error -> "unknown");

示例指定线程池,转换加载结果并提供降级值;业务是否允许降级要另行决定,不能吞掉所有失败。

  • thenApply 转换结果;thenCompose 用于回调返回另一个 Future,避免嵌套。
  • thenCombine 合并两个结果;allOf 等一组任务完成,不直接返回结果列表。
  • 非 Async 阶段可能由完成任务或其他参与线程执行;Async 版本可指定执行器。
  • 常用异步操作未指定执行器时通常使用公共 ForkJoinPool,不适合无边界放入大量阻塞调用。

get 通常通过 ExecutionException 包装失败,join 通常通过 CompletionException 暴露失败。等待超时不等于底层网络调用已取消,还要配置调用本身的超时。

面试回答模板#

原子类处理单值更新,LongAdder 适合统计。CountDownLatch 等待完成,CyclicBarrier 同步阶段,Semaphore 控制并发许可。BlockingQueue 连接生产者和消费者。Future 获取异步结果,CompletableFuture 进一步组合步骤;都要考虑线程池、超时、失败和取消。

自测#

  1. Semaphore(10) 是每秒最多 10 次吗?不是。
  2. allOf 直接返回全部结果列表吗?不返回,需要从各任务获取。
  3. Future.get 超时后任务一定停止吗?不一定。
JUC 常用工具与异步结果:原子类、同步器、队列与 Future
https://blog.xqcherry.top/posts/interview/java/juc-tools-and-futures/
作者
xqcherry
发布于
2026-10-12
许可协议
CC BY-NC-SA 4.0