1.创建异步任务
CompletableFuture.runAsync():创建一个没有返回值的异步任务。
CompletableFuture<Void> runComplete = CompletableFuture.runAsync(()-> System.out.println("没有返回值的异步任务"));
CompletableFuture.supplyAsync():常见一个有返回值的异步任务。
CompletableFuture<String> supportComplete = CompletableFuture.supplyAsync(()-> "有返回值的异步任务");
可以传入自定义的线程池执行任务:
ExecutorService executor = Executors.newCachedThreadPool();
CompletableFuture<Void> runComplete = CompletableFuture.runAsync(()-> System.out.println("没有返回值的异步任务"),executor);
CompletableFuture<String> supportComplete = CompletableFuture.supplyAsync(()-> "有返回值的异步任务",executor);
2.异步任务完成之后的回调
1️⃣ thenRun/thenRunAsync
thenRun通俗点讲就是,做完一个任务后,再做第二个任务。某个任务执行完成后,执行回调方法,但是前后两个任务没有参数传递,第二个任务也没有返回值。
CompletableFuture<String> supportComplete = CompletableFuture.supplyAsync(()->{
System.out.println("有返回值的异步任务");
return "有返回值的异步任务";
});
CompletableFuture<Void> thenRun = supportComplete.thenRun(() -> System.out.println("完成任务之后的回调,没有参数也没有返回值"));
System.out.println(thenRun.join());
thenRun/thenRunAsync的区别:
如果你执行第一个任务的时候,传入了一个自定义线程池:
- 调用thenRun方法执行第二个任务时,则第二个任务和第一个任务是共用同一个线程池。
- 调用thenRunAsync执行第二个任务时,则第一个任务使用的是你自己传入的线程池,第二个任务使用的是ForkJoin线程池。
2️⃣ thenAccept/thenAcceptAsync
thenAccept和thenAcceptAsync指的是做完第一个任务之后,将第一个任务的返回值作为参数传到thenAccept方法中,thenAccept和thenAcceptAsync没有返回值。
CompletableFuture<String> supportComplete = CompletableFuture.supplyAsync(()-> {
System.out.println("有返回值的异步 任务");
return "有返回值的异步任务";
});
CompletableFuture<Void> thenRun = supportComplete.thenAccept((s) -> System.out.println("完成任务之后的回调,有参数,参数为" + s + "没有返回值"));
System.out.println(thenRun.join());
两者的区别依然是共用线程池或者是第二个任务用ForkJoin线程池的区别。
3️⃣ thenApply和thenApplyAsync
thenApply和thenApplyAsync指的是第一个任务执行完成后,执行第二个回调方法任务,会将该任务的执行结果,作为入参,传递到回调方法中,并且回调方法是有返回值的。
CompletableFuture<String> supportComplete = CompletableFuture.supplyAsync(()-> {
System.out.println("有返回值的异步任务");
return "有返回值的异步任务";
});
CompletableFuture<String> thenRun = supportComplete.thenApplyAsync((s) -> {
System.out.println("完成任务之后的回调,有参数,参数为" + s + "有返回值");
return "完成任务之后的回调,有参数,参数为" + s + "有返回值";
});
System.out.println(thenRun.join());
thenApply和thenApplyAsync的区别和上面两者一样。
4️⃣ exceptionally
exceptionally方法表示,某个任务执行异常时,执行的回调方法;并且有抛出异常作为参数,传递到回调方法。参数为异常,有返回值。
CompletableFuture<String> supportComplete = CompletableFuture.supplyAsync(()-> {
System.out.println("有返回值的异步任务");
throw new RuntimeException();
});
CompletableFuture<String> exceptionFuture = supportComplete.exceptionally((e) -> {
e.printStackTrace();
return "程序出现异常";
});
System.out.println(exceptionFuture.get());
5️⃣ whenComplete
whenComplete方法表示,某个任务执行完成后,执行的回调方法,无返回值;并且whenComplete方法的参数是上个任务的结果。
CompletableFuture<String> supportComplete = CompletableFuture.supplyAsync(()-> {
System.out.println("有返回值的异步任务");
return "有返回值的异步任务";
});
CompletableFuture<String> whenComplete = supportComplete.whenComplete((e,throwable) -> {
System.out.println(e);
});
System.out.println(whenComplete.get());
whenComplete接收的参数为两个,第一个是上个任务的结果,另一个是异常。因此即使主任务有异常,依然会执行。
6️⃣:handle
handle和whenComplete差不多,都是表示某个任务执行完成后,执行的回调方法,handle方法的参数时上个任务的结果,但是handle是有返回值的,whenComplete没有返回值。
CompletableFuture<String> supportComplete = CompletableFuture.supplyAsync(()-> {
System.out.println("当前线程名称为:" + Thread.currentThread().getName());
System.out.println("有返回值的异步任务");
return "有返回值的异步任务";
});
CompletableFuture<String> handle = supportComplete.handle((e,throwable) -> {
System.out.println("当前线程名称为:" + Thread.currentThread().getName());
System.out.println(e);
return "有返回值";
});
System.out.println(handle.get());