本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

Java中CompletableFuture多线程任务异步编排

发布于2021-05-29 22:39     阅读(615)     评论(0)     点赞(24)     收藏(0)


今天来简单看一下CompletableFuture多线程任务异步编排

为什么需要CompletableFuture?

当多线程任务出现了相互依赖,需要按照一定的顺序执行的时候就需要用到CompletableFuture多线程任务异步编排

按照我的理解:CompletableFuture可以分为一下几种情况

1、单个任务

2、两任务的编排

3、三任务的编排

4、多任务的编排

一、单个任务

1、runAsync无返回值

  1. /**
  2. * runAsync无返回值
  3. */
  4. CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
  5. System.out.println("当前线程" + Thread.currentThread().getId());
  6. int i = 10 / 2;
  7. System.out.println("运行结果:" + i);
  8. }, executor);

2、supplyAsync有返回值

  1. /**
  2. * supplyAsync有返回值
  3. * whenComplete能感知异常,能感知结果,但没办法给返回值
  4. * exceptionally能感知异常,不能感知结果,能给返回值。相当于,如果出现异常就返回这个值
  5. */
  6. CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  7. System.out.println("当前线程" + Thread.currentThread().getId());
  8. int i = 10 / 0;
  9. System.out.println("运行结果:" + i);
  10. return i;
  11. }, executor).whenComplete((res,excption)->{
  12. //whenComplete虽然能得到异常信息,但是没办法修改返回值
  13. System.out.println("异步任务成功完成...结果是:"+res+";异常是:"+excption);
  14. }).exceptionally(throwable -> {
  15. //exceptionally能感知异常,而且能返回一个默认值,相当于,如果出现异常就返回这个值
  16. return 10;
  17. });

3、supplyAsync有返回值+handle

  1. /**
  2. * supplyAsync有返回值
  3. * handle能拿到返回结果,也能得到异常信息,也能修改返回值
  4. */
  5. CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  6. System.out.println("当前线程" + Thread.currentThread().getId());
  7. int i = 10 / 4;
  8. System.out.println("运行结果:" + i);
  9. return i;
  10. }, executor).handle((res,excption)->{
  11. if(excption!=null){
  12. return 0;
  13. }else {
  14. return res * 2;
  15. }
  16. });

二、两任务的编排

两任务组合(线程串行化)
可以是两任务的串行化,就是一个任务执行完了再执行下一个
也可以是多个任务的串行化,就是按照顺序一个个的执行

1、thenRunAsync

  1. /**
  2. * thenRunXXX 不能接收上一次的执行结果,也没返回值
  3. * .thenRunAsync(() -> {
  4. * System.out.println("任务2启动了...");
  5. * }, executor);
  6. */
  7. CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
  8. System.out.println("当前线程" + Thread.currentThread().getId());
  9. int i = 10 / 4;
  10. System.out.println("运行结果:" + i);
  11. return i;
  12. }, executor).thenRunAsync(() -> {
  13. System.out.println("任务2启动了...");
  14. }, executor);

2、thenAcceptAsync

  1. /**
  2. * thenAcceptXXX 能接收上一次的执行结果,但没返回值
  3. * .thenAcceptAsync(res->{
  4. * System.out.println("任务2启动了..."+res);
  5. * },executor);
  6. */
  7. CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
  8. System.out.println("当前线程" + Thread.currentThread().getId());
  9. int i = 10 / 4;
  10. System.out.println("运行结果:" + i);
  11. return i;
  12. }, executor).thenAcceptAsync(res -> {
  13. System.out.println("任务2启动了..." + res);
  14. }, executor);

3、thenApplyAsync

  1. /**
  2. * thenApplyXXX 能接收上一次的执行结果,又可以有返回值
  3. * .thenApplyAsync(res -> {
  4. * System.out.println("任务2启动了..." + res);
  5. * return "hello " + res;
  6. * }, executor);
  7. */
  8. CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
  9. System.out.println("当前线程" + Thread.currentThread().getId());
  10. int i = 10 / 4;
  11. System.out.println("运行结果:" + i);
  12. return i;
  13. }, executor).thenApplyAsync(res -> {
  14. System.out.println("任务2启动了..." + res);
  15. return "hello " + res;
  16. }, executor);

三、三任务的编排

先准备两个任务

  1. CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
  2. System.out.println("任务1线程" + Thread.currentThread().getId());
  3. int i = 10 / 4;
  4. System.out.println("任务1结束:");
  5. return i;
  6. }, executor);
  7. CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
  8. System.out.println("任务2线程" + Thread.currentThread().getId());
  9. try {
  10. Thread.sleep(3000);
  11. System.out.println("任务2结束:");
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. return "hello";
  16. }, executor);

1、三任务组合,前两个任务都完成,才执行任务3

1.1、runAfterBothAsync

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

  1. CompletableFuture<Void> future = future01.runAfterBothAsync(future02, () -> {
  2. System.out.println("任务3开始");
  3. }, executor);

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

  1. CompletableFuture<Void> future = future01.thenAcceptBothAsync(future02, (f1, f2) -> {
  2. System.out.println("任务3开始...得到之前的结果:f1:" + f1 + ", f2:" + f2);
  3. }, executor);

1.3、 thenCombineAsync

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

  1. CompletableFuture<String> future = future01.thenCombineAsync(future02, (f1, f2) -> {
  2. return f1+":"+f2+":哈哈";
  3. }, executor);

2、三任务组合,前两个任务只要有一个完成,就执行任务3

2.1、runAfterEitherAsync

两个任务只要有一个完成,就执行任务3,不感知结果,自己没返回值

  1. CompletableFuture<Void> future = future01.runAfterEitherAsync(future02, () -> {
  2. System.out.println("任务3开始...");
  3. }, executor);

2.2、acceptEitherAsync

两个任务只要有一个完成,就执行任务3,感知结果,自己没返回值

  1. CompletableFuture<Void> future = future01.acceptEitherAsync(future02, (res) -> {
  2. System.out.println("任务3开始...之前的结果" + res);
  3. }, executor);

2.3、applyToEitherAsync

两个任务只要有一个完成,就执行任务3,感知结果,自己有返回值

  1. CompletableFuture<String> future = future01.applyToEitherAsync(future02, (res) -> {
  2. System.out.println("任务3开始...之前的结果" + res);
  3. return "任务3的结果...";
  4. }, executor);

四、多任务的编排

  1. /**
  2. * 多任务组合
  3. */
  4. CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
  5. System.out.println("查询商品图片信息");
  6. return "hello.jpg";
  7. },executor);
  8. CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
  9. System.out.println("查询商品属性信息");
  10. return "黑色+256G";
  11. },executor);
  12. CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
  13. try {
  14. Thread.sleep(3000);
  15. System.out.println("查询商品介绍信息");
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. return "华为...";
  20. },executor);

1、allOf 所有任务都执行完

  1. /**
  2. * allOf 所有任务都执行完
  3. */
  4. CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
  5. allOf.get();//等待所有结果完成

2、anyOf 其中有一个任务执行完就可以

  1. /**
  2. * anyOf 其中有一个任务执行完就可以
  3. */
  4. CompletableFuture<Object> anyOf = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);
  5. anyOf.get();

 

原文链接:https://blog.csdn.net/ju_362204801/article/details/117325220



所属网站分类: 技术文章 > 博客

作者:以天使的名义

链接:http://www.javaheidong.com/blog/article/207887/5f296f7b922e0858a9c6/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

24 0
收藏该文
已收藏

评论内容:(最多支持255个字符)