Java8 新的异步编程方式 CompletableFuture 组合式 异步编程

  1. Java8新的异步编程方式 CompletableFuture
  2. 强大的CompletableFuture
  3. Java8新的异步编程方式 CompletableFuture(二)
  4. Java8新特性整理之CompletableFuture:组合式、异步编程(七)
  5. 分布式框架中使用CompletableFuture提高效率
  6. java8多线程异步调用 CompletableFuture 详解
  7. CompletableFuture 使用详解
  8. 如何编写优雅的异步代码 — CompletableFuture
  9. 搞定 CompletableFuture

CompletableFuture用法实例一

// runAsync() 无返回值  supplyAsync() 有返回值
CompletableFuture<Result> future2 = CompletableFuture.supplyAsync(() -> queryFeignService.listUsers(reqDTO));

log.info("remote result={}", future2.get());

//thenApply() thenApplyAsync() 转换 下面的例子,展示了数据流的类型经历了如下的转换:String -> Integer -> Double。
CompletableFuture<Double> future = CompletableFuture.supplyAsync(() -> "10")
    .thenApply(Integer::parseInt)
    .thenApply(i->i*10.0);

try {
    System.out.println(future.get());
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}
//执行结果:
100.0

//thenCompose() thenComposeAsync()可以用于组合多个CompletableFuture,将前一个结果作为下一个计算的参数,它们之间存在着先后顺序。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
    .thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World"));

try {
    System.out.println(future.get());
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}
//执行结果:
Hello World

//组合
//使用thenCombine() thenCombineAsync()之后future1、future2之间是并行执行的,最后再将结果汇总。这一点跟thenCompose()不同。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "100");
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 100);
CompletableFuture<Double> future = future1.thenCombine(future2, (s, i) -> Double.parseDouble(s + i));
try {
    System.out.println(future.get());
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}
//执行结果:
100100.0

//whenComplete() whenCompleteAsync()当CompletableFuture完成计算结果后,我们可能需要对结果进行一些处理。
CompletableFuture.supplyAsync(() -> "Hello")
                .thenApply(s->s+" World")
                .thenApply(s->s+ "\nThis is CompletableFuture demo")
                .thenApply(String::toLowerCase)
                .whenComplete((result, throwable) -> System.out.println(result));
//执行结果:
hello world
this is completablefuture demo

//handle() handleAsync() 执行完Action可以做转换
CompletableFuture<Double> future = CompletableFuture.supplyAsync(() -> "100")
                .thenApply(s->s+"100")
                .handle((s, t) -> s != null ? Double.parseDouble(s) : 0);

try {
    System.out.println(future.get());
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}
//执行结果:
100100.0
    
//thenAccept() thenAcceptAsync() 是只会对计算结果进行消费而不会返回任何结果的方法。
CompletableFuture.supplyAsync(() -> "Hello")
                .thenApply(s->s+" World")
                .thenApply(s->s+ "\nThis is CompletableFuture demo")
                .thenApply(String::toLowerCase)
                .thenAccept(System.out::print);
//执行结果:
hello world
this is completablefuture demo

CompletableFuture实例二

@RequestMapping("/getStudentInfoWithCompletableFuture")
public Object getStudentInfoWithCompletableFuture() {
    long start = System.currentTimeMillis();
    Map<String, Object> resultMap = new HashMap<>(10);

    try {
        CompletableFuture<Object> completableFutureStudentName = CompletableFuture.supplyAsync(() -> {
            try {
                return studentService.getStudentName();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        });

        CompletableFuture<Object> completableFutureSutdentAge = CompletableFuture.supplyAsync(() -> {
            try {
                return studentService.getSutdentAge();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        });

        CompletableFuture<Object> completableFutureFamilyInfo = CompletableFuture.supplyAsync(() -> {
            try {
                return studentService.getSutdentFamilyInfo();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        });

        CompletableFuture.allOf(completableFutureStudentName, completableFutureSutdentAge, completableFutureFamilyInfo).join();

        resultMap.put("studentName", completableFutureStudentName.get());
        resultMap.put("studentAge", completableFutureSutdentAge.get());
        resultMap.put("studentFamilyInfo", completableFutureFamilyInfo.get());

    } catch (Exception e) {
        resultMap.put("errMsg", e.getMessage());
    }

    resultMap.put("total cost", System.currentTimeMillis() - start);

    return resultMap;
}
//自带最后的同步等待,不需要 CountDownLatch。CompletableFuture 还有很多其他好用的方法。

CompletableFuture 同步和异步实例三

/**
* 定义接口 同步和异步方法
*/
public interface AsyncInterfaceExample {

    String computeSomeThine();

    CompletableFuture<String> computeSomeThingAsync();
}

/**
* 同步方法异步化
*/
public class AsyncInterfaceExampleImpl implements AsyncInterfaceExample {

    @Override
    public String computeSomeThine() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "hello, world";
    }

    @Override
    public CompletableFuture<String> computeSomeThingAsync() {
        return CompletableFuture.supplyAsync(this::computeSomeThine);
    }
}

/**
* 测试类
*/
public class AsyncInterfaceExampleTest {

    private static String getOtherThing() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "other";
    }

public static void main(String[] args) {
     AsyncInterfaceExample asyncInterfaceExample = new AsyncInterfaceExampleImpl();

     //case1 同步调用
     long start = System.currentTimeMillis();
     String someThing = asyncInterfaceExample.computeSomeThine();
     String other = getOtherThing();
     System.out.println("cost:" + (System.currentTimeMillis() - start) + "  result:" + someThing + other);

     //case2 异步调用,使用回调
     start = System.currentTimeMillis();
     CompletableFuture<String> someThingFuture = asyncInterfaceExample.computeSomeThingAsync();
     other = getOtherThing();

     long finalStart = start;
     String finalOther = other;
     someThingFuture.whenComplete((returnValue, exception) -> {
         if (exception == null) {
             System.out.println(
                 "cost:" + (System.currentTimeMillis() - finalStart) + "  result:" + returnValue + finalOther);
         } else {
             exception.printStackTrace();
         }
     });
   }
}

你可能感兴趣的:(多线程异步并发)