异步编程CompletionService

CompletionService 是 Java 并发包(java.util.concurrent)里的一个 "异步结果收割机"

它把「提交任务」和「拿结果」两件事解耦:

你只管往里扔任务;它帮你盯着谁先跑完,让你 按完成顺序 取结果,而不是按提交顺序。


一、核心 API(就 4 个常用方法)

方法 作用
submit(Callable/Runnable) 扔一个任务进去
take() 阻塞 直到有任务完成,返回完成的 Future
poll() 立刻返回,如果没有已完成的任务返回 null
poll(timeout, unit) 等指定时间,超时返回 null

二、使用套路(3 步曲)

  1. 创建线程池 + CompletionServic

    复制代码
    ExecutorService pool = Executors.newFixedThreadPool(4);
    CompletionService<String> cs = new ExecutorCompletionService<>(pool);
  2. 批量提

    复制代码
    for (int i = 0; i < 10; i++) {
        final int no = i;
        cs.submit(() -> {
            Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 3000));
            return "task-" + no;
        });
    }
  3. 按完成顺序收割

    复制代码
    for (int i = 0; i < 10; i++) {
        String result = cs.take().get();   // 谁先跑完谁先拿到
        System.out.println(result);
    }
    pool.shutdown();

三、场景举例

  • 并发下载:10 张图片同时开线程下,下好一张立刻显示一张,不用等全部下完。

  • 并发调用多服务:A、B、C 三个微服务都查一遍,谁返回快就用谁的数据。

  • 并行计算:跑 100 个 Monte-Carlo 任务,每算完一个就汇总,不用等全部结束再统计。


四、对比"裸用 FutureList"

方式 拿结果顺序 是否阻塞
List<Future> 按提交顺序 会卡在还没跑完的任务
CompletionService 按完成顺序 只阻塞在 take(),总有结果就返回

五、完整可运行 Demo

复制代码
import java.util.concurrent.*;
public class Demo {
    public static void main(String[] args) throws Exception {
        ExecutorService pool = Executors.newFixedThreadPool(4);
        CompletionService<Integer> cs = new ExecutorCompletionService<>(pool);

        // 1. 提交 5 个耗时不一样的任务
        for (int i = 1; i <= 5; i++) {
            final int sec = i;
            cs.submit(() -> {
                TimeUnit.SECONDS.sleep(sec);
                return sec;
            });
        }

        // 2. 按完成顺序打印
        for (int i = 0; i < 5; i++) {
            Integer who = cs.take().get();
            System.out.println("任务 " + who + " 秒完成!");
        }
        pool.shutdown();
    }
}

运行结果(每次都一样):

任务 1 秒完成!

任务 2 秒完成!

任务 3 秒完成!

任务 4 秒完成!

任务 5 秒完成!


一句话总结:
CompletionService = 线程池 + 优先队列 ,让你 先做完的先拿走,写并行流水线最舒服。

相关推荐
num_killer12 小时前
小白的Langchain学习
java·python·学习·langchain
期待のcode12 小时前
Java虚拟机的运行模式
java·开发语言·jvm
程序员老徐12 小时前
Tomcat源码分析三(Tomcat请求源码分析)
java·tomcat
a程序小傲13 小时前
京东Java面试被问:动态规划的状态压缩和优化技巧
java·开发语言·mysql·算法·adb·postgresql·深度优先
仙俊红13 小时前
spring的IoC(控制反转)面试题
java·后端·spring
阿湯哥13 小时前
AgentScope Java 集成 Spring AI Alibaba Workflow 完整指南
java·人工智能·spring
小楼v13 小时前
说说常见的限流算法及如何使用Redisson实现多机限流
java·后端·redisson·限流算法
与遨游于天地13 小时前
NIO的三个组件解决三个问题
java·后端·nio
czlczl2002092513 小时前
Guava Cache 原理与实战
java·后端·spring
yangminlei14 小时前
Spring 事务探秘:核心机制与应用场景解析
java·spring boot