CompletableFuture使用
java8新引入的异步编程方式
使用方式
开启异步
supplyAsync(有返回值)
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行"); return "异步运行完成"; }); future.join(); // 等待异步任务完成并获取结果 } 复制代码
runAsync(无返回值)
public static void main(String[] args) { CompletableFuture<Void> future = CompletableFuture.runAsync(()-> { System.out.println("开始异步运行"); }); future.join(); // 等待异步任务完成 } 复制代码
默认是开启的异步守护线程,如果没有调用异步结果,主线程先结束的话,异步任务未完成也会直接结束。
调用异步结果,主线程会等待异步任务完成,获取结果再继续运行。
连接两个异步任务
thenCompose
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1"); return "异步运行完成1"; }).thenCompose(result -> CompletableFuture.supplyAsync(()->{ System.out.println("异步任务1结果:" + result); System.out.println("开始异步运行2"); return "异步运行完成2"; })); future.join(); // 获取异步结果(得到的是2的结果) } 复制代码
做任务的后置处理
thenApply(有返回值)
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1"); return "异步运行完成1"; }).thenApply(result -> { System.out.println("异步任务1结果:" + result); System.out.println("开始异步运行2"); return "异步运行完成2"; )); future.join(); // 获取异步结果(得到的是2的结果) } 复制代码
thenAccept(无返回值)
public static void main(String[] args) { CompletableFuture<Void> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1"); return "异步运行完成1"; }).thenAccept(result -> { System.out.println("异步任务1结果:" + result); System.out.println("开始异步运行2"); )); future.join(); // 等待异步任务完成 } 复制代码
thenRun(无入参,无返回值)
public static void main(String[] args) { CompletableFuture<Void> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1"); return "异步运行完成1"; }).thenRun(() -> { System.out.println("开始异步运行2"); )); future.join(); // 等待异步任务完成 } 复制代码
组合处理
thenCombine(有返回值)
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1"); return "异步运行完成1"; }).thenCombine(CompletableFuture.supplyAsync(()->{ System.out.println("开始异步运行2"); return "异步运行完成2"; }), (x, y) -> { System.out.println("异步任务1结果:" + x); System.out.println("异步任务2结果:" + y); return "返回最终结果"; }); future.join(); // 获取异步结果(得到的是最终的结果) } 复制代码
任务1和任务2分别开了不同的线程运行。
thenAcceptBoth(无返回值)
public static void main(String[] args) { CompletableFuture<Void> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1"); return "异步运行完成1"; }).thenAcceptBoth(CompletableFuture.supplyAsync(()->{ System.out.println("开始异步运行2"); return "异步运行完成2"; }), (x, y) -> { System.out.println("异步任务1结果:" + x); System.out.println("异步任务2结果:" + y); }); future.join(); // 等待异步任务完成 } 复制代码
runAfterBoth(无入参,无返回值)
public static void main(String[] args) { CompletableFuture<Void> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1"); return "异步运行完成1"; }).runAfterBoth(CompletableFuture.supplyAsync(()->{ System.out.println("开始异步运行2"); return "异步运行完成2"; }), () -> { System.out.println("开始异步运行3"); }); future.join(); // 等待异步任务完成 } 复制代码
优先处理
applyToEither(有返回值)
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1, 需要时间3s"); return "异步运行完成1"; }).applyToEither(CompletableFuture.supplyAsync(()->{ System.out.println("开始异步运行2, 需要时间2s"); return "异步运行完成2"; }), result -> result); future.join(); // 获取异步结果(先处理完的结果) } 复制代码
acceptEither(无返回值)
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1, 需要时间3s"); return "异步运行完成1"; }).acceptEither(CompletableFuture.supplyAsync(()->{ System.out.println("开始异步运行2, 需要时间2s"); return "异步运行完成2"; }), result -> { System.out.println("处理结果:" + result); }); future.join(); // 等待异步任务完成 } 复制代码
runAfterEither(无入参,无返回值)
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1, 需要时间3s"); return "异步运行完成1"; }).runAfterEither(CompletableFuture.supplyAsync(()->{ System.out.println("开始异步运行2, 需要时间2s"); return "异步运行完成2"; }), () -> { System.out.println("后续操作"); }); future.join(); // 等待异步任务完成 } 复制代码
异常处理
exceptionally(只接收异常,返回备用方案)
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1, 需要时间3s"); return "异步运行完成1"; }).applyToEither(CompletableFuture.supplyAsync(()->{ System.out.println("开始异步运行2, 需要时间2s"); return "异步运行完成2"; }), result -> result).exceptionally(e -> { System.out.println("异常处理"); return "备用方案"; }); future.join(); // 获取异步结果(出现异常了,返回备用方案) } 复制代码
handle(接收异常和结果,返回最终方案)
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1, 需要时间3s"); return "异步运行完成1"; }).applyToEither(CompletableFuture.supplyAsync(()->{ System.out.println("开始异步运行2, 需要时间2s"); return "异步运行完成2"; }), result -> result).handle((e, s) -> { if(e != null) { System.out.println("异常处理:" + e.getMessage()); } System.out.println("未出异常, 结果:" + s); return "最终方案"; }); future.join(); // 获取异步结果(返回最终方案) } 复制代码
whenComplete(接收异常和结果,无返回值)
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1, 需要时间3s"); return "异步运行完成1"; }).applyToEither(CompletableFuture.supplyAsync(()->{ System.out.println("开始异步运行2, 需要时间2s"); return "异步运行完成2"; }), result -> result).whenComplete((s, e) -> { if(e != null) { System.out.println("异常处理:" + e.getMessage()); } System.out.println("未出异常, 结果:" + s); }); future.join(); // 获取异步结果(whenComplete不影响异步结果) } 复制代码
xxx和xxxAsync(e: thenApply() 和thenApplyAsync())
xxx
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1"); return "异步运行完成1"; }).thenApply(result -> { System.out.println("异步任务1结果:" + result); System.out.println("开始异步运行2"); return "异步运行完成2"; )); future.join(); // 获取异步结果(得到的是2的结果) } 复制代码
另起一个线程,先完成异步任务1
,再完成异步任务2
。
xxxAsync
public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> { System.out.println("开始异步运行1"); return "异步运行完成1"; }).thenApplyAsync(result -> { System.out.println("异步任务1结果:" + result); System.out.println("开始异步运行2"); return "异步运行完成2"; )); future.join(); // 获取异步结果(得到的是2的结果) } 复制代码
另起一个线程,完成异步任务1
,再起一个线程完成异步任务2
作者:某某小孩
链接:https://juejin.cn/post/7025810389052948493