CompletableFuture异步编排

文章介绍了CompletableFuture作为FutureTask的增强版,在处理异步任务时提供了更多的功能,如支持回调、链式调用、异常处理等。文中通过创建无返回值和有返回值的任务,展示了如何使用CompletableFuture与线程池协同工作,以及如何接收和处理前一个任务的结果。
摘要由CSDN通过智能技术生成

一、简介

从实现类的版本情况能看出,CompletableFuture是FutureTask的升级版。

CompletableFuture相比较于Callable+FutureTask组合、相比较于Future接口定义的基础功能确实做了诸多改进:

  • 支持异步回调
  • 手动完成任务并返回兜底值
  • 支持进一步的非阻塞调用
  • 支持链式调用
  • 支持多任务合并
  • 支持异常处理

二、具体用法

1、创建无返回值任务

// Demo 01:创建三个没有返回值的线程
// 1、创建自定义线程池
// [1]线程池的核心线程数
int corePoolSize = 3;

// [2]线程池的最大线程数
int maximumPoolSize = 5;

// [3]设置最大过期时间的数量
long keepAliveTime = 10;

// [4]设置最大过期时间的单位
TimeUnit timeUnit = TimeUnit.SECONDS;

// [5]存放等待中任务的阻塞队列
ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);

// [6]创建线程工厂
ThreadFactory threadFactory = Executors.defaultThreadFactory();

// [7]创建拒绝策略对象
ThreadPoolExecutor.AbortPolicy abortPolicy = new ThreadPoolExecutor.AbortPolicy();

ThreadPoolExecutor threadPoolExecutor =
        new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                timeUnit,
                queue,
                threadFactory,
                abortPolicy);

// 2、使用 CompletableFuture 开辟新线程执行任务
CompletableFuture.runAsync(()->{
    while (true) {
        try {
            TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}

        System.out.println(Thread.currentThread().getName() + " is working");
    }
}, threadPoolExecutor);

CompletableFuture.runAsync(()->{
    while (true) {
        try {
            TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}

        System.out.println(Thread.currentThread().getName() + " is working");
    }
}, threadPoolExecutor);

CompletableFuture.runAsync(()->{
    while (true) {
        try {
            TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}

        System.out.println(Thread.currentThread().getName() + " is working");
    }
}, threadPoolExecutor);

2、创建有返回值任务

// 1、获取线程池对象
ThreadPoolExecutor threadPool = ThreadPoolProvider.getThreadPool();

// 2、创建 “任务带有返回值” 的线程
CompletableFuture<String> future01 = CompletableFuture.supplyAsync(() -> {

    System.out.println(Thread.currentThread().getName() + " is working");

    return "task 01 result";
}, threadPool);

CompletableFuture<String> future02 = CompletableFuture.supplyAsync(()->{

    System.out.println(Thread.currentThread().getName() + " is working");

    return "task 02 result";
}, threadPool);

CompletableFuture<String> future03 = CompletableFuture.supplyAsync(()->{

    System.out.println(Thread.currentThread().getName() + " is working");

    try {
        TimeUnit.SECONDS.sleep(10);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    return "task 03 result";
}, threadPool);

// 3、获取各个任务的执行结果
// get()方法会阻塞 main 线程(当前线程),一直到执行线程内任务的方法返回
String task01Result = future01.get();
System.out.println("task01Result = " + task01Result);

String task02Result = future02.get();
System.out.println("task02Result = " + task02Result);

String task03Result = future03.get();
System.out.println("task03Result = " + task03Result);

3、接收前面任务结果

// 测试目标:任务 1 处理完成之后,再处理任务 2,而且把任务 1 的结果传递给任务 2
// 1、获取线程池对象
ThreadPoolExecutor threadPool = ThreadPoolProvider.getThreadPool();

// 2、封装线程任务:链式执行
String finalTaskResult = CompletableFuture
        .supplyAsync(() -> "prev task result", threadPool)
        .thenApply((String prevTaskResult) -> { // 这里 Function 接口 apply() 方法入参是前面任务的返回值

            // 打印前面任务传入的结果
            System.out.println("prevTaskResult = " + prevTaskResult);

            // 返回当前任务的结果
            return prevTaskResult + "~~~~~~~~~~~";
        }).get();

System.out.println("finalTaskResult = " + finalTaskResult);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值