异步多线程 CompletableFuture

  • Post author:
  • Post category:其他




一、单个任务



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



版权声明:本文为qq_44845473原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。