CompletableFuture的简单使用

简述CompletableFuture

CompletableFuture既可以看作是多线程,也可以看作是异步任务。

CompletableFuture是Java 8中引入的一个类,它提供了一种简单、灵活和强大的方式来处理异步操作。它允许你在等待一个异步操作完成时执行其他代码,并且可以使用回调函数或组合多个CompletableFuture来处理结果。这些特性使得CompletableFuture非常适合处理IO密集型或CPU密集型的任务。

在实现上,CompletableFuture通常会使用多线程来执行任务。当你调用CompletableFuture的异步方法时,它会将任务提交给线程池中的一个线程来执行。这样就可以避免阻塞主线程,提高程序的并发性和响应速度。

因此,可以说CompletableFuture既包含了多线程的特性(通过线程池来执行任务),又包含了异步任务的特性(允许在等待IO完成时执行其他代码)。

创建一个线程池

ExecutorService executor = Executors.newFixedThreadPool(10);

CompletableFuture没有返回值的用法

没有返回值的异步任务,使用自己的线程池执行异步任务,如果不添加executor,那么使用的是默认的线程池。

CompletableFuture.runAsync(() -> {
            System.out.println("Thread.currentThread() = " + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("i = " + i);
        },executor);

CompletableFuture有返回值的用法

创建一个有返回值的异步任务,如果链式调用handle方法完成异步任务结束的操作,接收值为异步任务的返回值和异常;如果链式调用whenComplete方法,任务完成后的感知,如果存在异常返回future为null,异常名,成功正常显示future值;如果链式调用exceptionally方法,感知到异常将默认值返回。

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("Thread.currentThread() = " + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("i = " + i);
            return i;
        }, executor)
                // 方法完成后的处理
                .handle((res,exception) -> {
            if (res != null){
                return res * 2;
            }
            if (exception != null){
                return 1;
            }
            return 0;
        });
//                // 完成后的感知,如果存在异常返回future为null,异常名,成功正常显示future值
//                .whenComplete((res, exception) -> {
//            System.out.println("结果是" + res + "和异常" + exception);
//        })
//                // 感知到异常将默认值返回
//                .exceptionally((throwable) -> {
//                    System.out.println("默认值为0");
//                    return 0;
//                });
        // 打印出future的结果
        System.out.println("future.get() = " + future.get());

CompletableFuture的线程串行化

创建一个有返回值的异步任务,链式调用thenRunAsync方法来将线程串行化,此方法不能获取到上一步的结果,无返回值,加Async新开一个线程,否则用上一个异步任务的线程;链式调用thenAcceptAsync方法,能获取到上一步的结果,无返回值;链式调用thenApplyAsync方法,能获取到上一步的结果,有返回值,加Async新开一个线程,否则用上一个线程。

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
                    System.out.println("Thread.currentThread() = " + Thread.currentThread().getId());
                    int i = 10 / 2;
                    System.out.println("i = " + i);
                    return i;
                }, executor)
//                不能获取到上一步的结果,无返回值,加Async新开一个线程,否则用上一个线程
//                .thenRunAsync(() -> {
//            System.out.println("任务2启动");
//        });
//                能获取到上一步的结果,无返回值,加Async新开一个线程,否则用上一个线程
//                .thenAcceptAsync((res) -> {
//                    System.out.println("上一个任务的返回值 = " + res);
//                })
                // 能获取到上一步的结果,有返回值,加Async新开一个线程,否则用上一个线程
                .thenApplyAsync((res) -> {
                    System.out.println("上一个任务的返回值 = " + res);
                    return res * 2;
                });

        // 打印出future1的结果
        System.out.println("future1.get() = " + future.get());

CompletableFuture的双任务组合

创建两个有返回值的异步任务,使用其中的一个异步任务点击调用runAfterEitherAsync方法,传入第二个异步任务,当其中一个任务完成后执行lambda表达式中的代码;acceptEitherAsync方法能接受上面传来的返回值,applyToEitherAsync方法能够接受返回值并将自己的返回值return。

// 双任务有一个完成后执行
CompletableFuture<Integer> future5 = CompletableFuture.supplyAsync(() -> {
    System.out.println("Thread.currentThread() = " + Thread.currentThread().getId());
    System.out.println("任务1开始");
    int i = 10 / 2;
    System.out.println("i = " + i);
    return i;
}, executor);
CompletableFuture<Integer> future6 = CompletableFuture.supplyAsync(() -> {
    System.out.println("Thread.currentThread() = " + Thread.currentThread().getId());
    System.out.println("任务2开始");
    int i = 10 / 2;
    System.out.println("i = " + i);
    return i;
}, executor);

// 两任务有一个完成就执行
// 不接收返回值
future5.runAfterEitherAsync(future6,()->{
    System.out.println("任务3开始");
},executor);
// 接收返回值
future5.acceptEitherAsync(future6,(res)->{
    System.out.println("任务3开始" + res);
},executor);
// 接受返回值并返回值
future5.applyToEitherAsync(future6,(res)->{
    System.out.println("任务3开始" + res);
    return res;
},executor);

CompletableFuture的多任务组合

创建三个异步任务,调用allOf方法等待所有线程结束,使用get方法进行阻塞,anyOf方法则是等其中任意的的线程结束。

// 多任务组合
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
    System.out.println("Thread.currentThread() = " + Thread.currentThread().getId());
    System.out.println("查询商品图片信息");
    return "msg";
}, executor);
CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
    System.out.println("Thread.currentThread() = " + Thread.currentThread().getId());
    System.out.println("查询商品图片信息");
    return "msg";
}, executor);
CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
    System.out.println("Thread.currentThread() = " + Thread.currentThread().getId());
    System.out.println("查询商品图片信息");
    return "msg";
}, executor);
// 等所有的线程结束,get方法进行阻塞
CompletableFuture.allOf(futureImg, futureAttr, futureDesc).get();
// 等其中任意的的线程结束,get方法进行阻塞
CompletableFuture.anyOf(futureImg, futureAttr, futureDesc).get();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值