异步多线程 CompletableFuture

本文详细介绍了Java中CompletableFuture的使用,包括无返回值的runAsync,有返回值的supplyAsync及其whenComplete、exceptionally、handle方法的用法,以及如何进行多任务的串行化组合,如thenRunAsync、thenApplyAsync、runAfterBothAsync、thenAcceptBothAsync、thenCombineAsync,最后讲解了allOf和anyOf在多任务组合中的应用。通过实例展示了每个方法的执行流程和结果,帮助读者深入理解Future的异步处理和任务组合方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、单个任务

1、runAsync: 无返回值

 /** runAsync 无返回值 */
        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{
            System.out.println("线程" + Thread.currentThread().getName());
        });

2、supplyAsync:有返回值

2.1 whenComplete

示例:能感知结果,无法修改返回值;能感知异常

/** 可以感知结果,感知异常,但是没有返回值,抛异常也无法被外部感知 */
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(()->{
            System.out.println("1、线程" + Thread.currentThread().getName());
            return 0;
        },executorService).whenComplete((res, exception)->{
            System.out.println("2、可获得结果" + res + "可获取异常" + exception);
            throw new BadRequestAlertException("抛出异常不会被外部感知");
        });
        try {
            System.out.println("3、通过future.get()获取结果" + future.get());
        }catch (Exception e){
            System.out.println("4、异常");
        }

控制台打印:

1、线程pool-1-thread-1
2、可获得结果0可获取异常null
4、异常

2.2 exceptionally

示例:可以处理异常,替换返回值,不能接收传入结果

/** exceptionally:可以处理异常,替换返回值,不能接收传入结果 */
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(()->{
            System.out.println("1、线程" + Thread.currentThread().getName());
            return 0;
        },executorService).whenComplete((res, exception)->{
            System.out.println("2、可获得结果" + res + "可获取异常" + exception);
            throw new BadRequestAlertException("抛出异常不会被外部感知");
        }).exceptionally(throwable -> 1);
        try {
            System.out.println("3、通过future.get()获取结果" + future.get());
        }catch (Exception e){
            System.out.println("4、异常");
        }

控制台打印:

1、线程pool-1-thread-1
2、可获得结果0可获取异常null
3、通过future.get()获取结果1

2.3 handle

示例:可获得返回结果,可获得异常信息,也能修改返回值

	    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(()->{
            System.out.println("1、线程:" + Thread.currentThread().getName());
            return 0;
        },executorService).handle((res, exception)-> exception == null ? 1 : 2);
        try {
            System.out.println("3、通过future.get()获取结果:" + future.get());
        }catch (Exception e){
            System.out.println("4、异常");
        }

控制台打印:

1、线程:pool-1-thread-1
3、通过future.get()获取结果:1

二、任务组合(2线程串行化)

1、thenRunAsync:

示例:不能接收上一次的执行结果,也没返回值

		ExecutorService executorService = Executors.newFixedThreadPool(10);
        CompletableFuture<Void> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println("1、线程:" + Thread.currentThread().getName());
            return 0;
        },executorService).thenRunAsync(()->{
            System.out.println("2、线程:" + Thread.currentThread().getName());
        },executorService);
        try       {
            System.out.println("3、通过future.get()获取结果:" + future1.get());
        }catch (Exception e){
            System.out.println("4、异常");
        }

控制台打印:

1、线程:pool-1-thread-1
2、线程:pool-1-thread-2
3、通过future1.get()获取结果:null

2、thenApplyAsync

示例:能接收上次执行结果,有返回值

		ExecutorService executorService = Executors.newFixedThreadPool(10);
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println("1、线程:" + Thread.currentThread().getName());
            return "线程1返回值";
        },executorService).thenApplyAsync((res)->{
            System.out.println("2、线程:" + Thread.currentThread().getName());
            return "线程2返回值";
        },executorService);
        try{
            System.out.println("3、通过future.get()获取结果:" + future1.get());
        }catch (Exception e){
            System.out.println("4、异常");
        }

控制台打印:

1、线程:pool-1-thread-1
2、线程:pool-1-thread-2
3、通过future.get()获取结果:线程2返回值

三、任务组合(3线程串行化)

准备两个任务:

		ExecutorService executorService = Executors.newFixedThreadPool(10);
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println("1、线程:" + Thread.currentThread().getName());
            return "线程1返回值";
        },executorService);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->{
            System.out.println("2、线程:" + Thread.currentThread().getName());
            return "线程2返回值";
        },executorService);

1、runAfterBothAsync:

示例:任务01 任务02都完成了,再开始执行任务3,不感知任务1、2的结果的,也没返回值

		CompletableFuture<Void> future3 = future1.runAfterBothAsync(future2,()->{
            System.out.println("3、线程:" + Thread.currentThread().getName());
        });

控制台打印:

1、线程:pool-1-thread-1
2、线程:pool-1-thread-2
3、线程:ForkJoinPool.commonPool-worker-9

2、thenAcceptBothAsync:

示例:任务01 任务02都完成了,再开始执行任务3,能感知到任务1、2的结果,但没返回值

 		CompletableFuture<Void> future3 = future1.thenAcceptBothAsync(future2,(res1,res2)->{
            System.out.println("3、线程:" + Thread.currentThread().getName() + "\n"
                    + "线程1结果: "+ res1+ "\n线程2结果:" + res2 );
        });
        // 打印最后执行线程的返回值
        try{
            System.out.println("4、通过future.get()获取结果:" + future3.get());
        }catch (Exception e){
            System.out.println("5、异常");
        }

控制台打印:

1、线程:pool-1-thread-1
2、线程:pool-1-thread-2
3、线程:ForkJoinPool.commonPool-worker-9
线程1结果: 线程1返回值
线程2结果:线程2返回值
4、通过future.get()获取结果:null

thenCombineAsync:

示例:任务01 任务02都完成了,再开始执行任务3,能感知到任务1、2的结果,而且自己可以带返回值

		 CompletableFuture<String> future3 = future1.thenCombineAsync(future2,(res1,res2)->{
            System.out.println("3、线程:" + Thread.currentThread().getName() + "\n"
                    + "线程1结果: "+ res1+ "\n线程2结果:" + res2 );
            return "线程3结果";
        });
        // 打印最后执行线程的返回值
        try{
            System.out.println("4、通过future.get()获取结果:" + future3.get());
        }catch (Exception e){
            System.out.println("5、异常");
        }

控制台打印:

1、线程:pool-1-thread-1
2、线程:pool-1-thread-2
3、线程:ForkJoinPool.commonPool-worker-9
线程1结果: 线程1返回值
线程2结果:线程2返回值
4、通过future.get()获取结果:线程3结果

四、多任务组合

准备三个任务

 		ExecutorService executorService = Executors.newFixedThreadPool(10);
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println("1、线程:" + Thread.currentThread().getName());
            return "线程1返回值";
        },executorService);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->{
            System.out.println("2、线程:" + Thread.currentThread().getName());
            return "线程2返回值";
        },executorService);
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(()->{
            System.out.println("3、线程:" + Thread.currentThread().getName());
            return "线程3返回值";
        },executorService);

1、allOf:

示例:所有任务都执行完

		CompletableFuture<String> future3 = CompletableFuture.supplyAsync(()->{
            System.out.println("3、线程:" + Thread.currentThread().getName());
            return "线程3返回值";
        },executorService);
        CompletableFuture<Void> future = CompletableFuture.allOf(future1,future2,future3);
      
        try{
            System.out.println("4、通过future.get()获取结果:" + future.get());
        }catch (Exception e){
            System.out.println("5、异常");
        }
        System.out.println("等待3个线程执行完毕");

控制台打印:

1、线程:pool-1-thread-1
2、线程:pool-1-thread-2
3、线程:pool-1-thread-3
4、通过future.get()获取结果:null
等待3个线程执行完毕

2、anyOf:

示例:其中有一个任务执行完就可以

		CompletableFuture<String> future3 = CompletableFuture.supplyAsync(()->{
            System.out.println("3、线程:" + Thread.currentThread().getName());
            return "线程3返回值";
        },executorService);
        CompletableFuture<Object> future = CompletableFuture.anyOf(future1,future2,future3);
        try{
            System.out.println("4、通过future.get()获取结果:" + future.get());
        }catch (Exception e){
            System.out.println("5、异常");
        }
        System.out.println("有一个任务执行完毕即可往下执行");

控制台打印:

1、线程:pool-1-thread-1
2、线程:pool-1-thread-2
4、通过future.get()获取结果:线程1返回值
等待3个线程执行完毕
3、线程:pool-1-thread-3

参考博客:
https://blog.csdn.net/u014571143/article/details/125617736

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值