public static void main(String[] args) throws InterruptedException, ExecutionException { // SpringApplication.run(MyApplication.class, args); // String a="123"; // Integer b=789; // double a1=System.nanoTime()/1e13; // CompletableFuture<String> threadA=CompletableFuture.supplyAsync() // ExecutorService executorService= Executors.newFixedThreadPool(3); // //supplyAsync()可以定义返回值,现在使用的runAsync()由于传入的是Rnnable接口,是没有返回值的 // CompletableFuture<Void> exceptionally = CompletableFuture.runAsync(() -> { // System.out.println("dfgdgfdj"); // // }).whenComplete((r, e) -> { // System.out.println("执行结果为"+r); // //System.out.println("打印的异常为"+e.getMessage()); // }).exceptionally(e -> { // e.printStackTrace(); // System.out.println("ddsdsd"); // return null; // }); // System.out.println("exceptionally.get() = " + exceptionally.get()); // TimeUnit.SECONDS.sleep(3);//线程阻塞的方法 // // CompletableFuture.supplyAsync(()->{ // return "ssss"; // }).thenApply(s -> { // return "ssss+thenApply"; // }); //相当于 new Thread()类来实现多线程 // 1.supplyAsync 有返回值 //2.并且可以通过一个对象来接收,并调用get()方法来获取异步的结果 //类比于callAble接口 CompletableFuture<String> supplyAsyncTest = CompletableFuture.supplyAsync(() -> { // int a=1/0; return "tset"; }); //supplyAsyncTest.get(); //CompletableFuture.runAsync 相当于会启动一个线程。runAsync 无返回值 //类比于runable接口 CompletableFuture<Void> runAsyncTest = CompletableFuture.runAsync(() -> { }); //当有一个新的异步任务需要依赖于第一个异步任务的结果时, // 比如需要先获取到supplyAsyncTest的结果后,再进行操作 //thenApply 有入参,有返回值 //thenAccept 有入参 无返回值 //thenRun 无入参 无返回值 //三个方法都会返回一个新的CompletableFuture对象 //缺点是 没法捕获异常 CompletableFuture<Boolean> booleanCompletableFuture = supplyAsyncTest.thenApply(t -> { return true; }); supplyAsyncTest.thenAccept(t->{ if (t.equals("")){ } }); supplyAsyncTest.thenRun(()->{ //throw new Exception(); System.out.println("\"thenRun\" = " + "thenRun"); }); //当需要一个新的异步任务 需要对上一个的异步任务的结果和异常都进行捕获时, // 可以使用whenComplete 和handle方法 他们的区别是 whenComplete 只有入参无返回值 // handle方法 可以有入参和 返回值 //目前比如来说一个新的异步任务,需要使用supplyAsyncTest的返回值时和异常时,可以使用whenComplete方法 //whenComplete 和handle都会开启一个新的异步线程 supplyAsyncTest.whenComplete((t,e)->{ System.out.println(" 之前的任务的返回结果是 t = " + t); System.out.println("之前的任务的异常结果是 e = " + e); }); supplyAsyncTest.handle((returnMes,e)->{ return returnMes; }); //上面的方法是针对 一个异步任务需要依赖之前的执行结果时,才会用到的方法 //总结一下: 只使用结果,不关注异常(或者保证不会异常的时候)可以用thenApply,thenAccept,thenRun方法 //区别是 thenApply 同时支持入参,有返回值 thenAccept 有入参无返回值 thenRun无入参和无返回值 //当需要同时关注 返回结果和异常时,可以使用whenComplete 和 handle方法 // 区别是 handle有返回值 whenComplete无返回值 //---------------------------------------------------------------------------------------- //当需要对两个并无关系的异步任务进行编排时,并且两个任务都成功时才会进行下一步的, // 否则一个出现异常,会将异常结果作为返回值 // thenComebine, 有入参,一个参数是新的异步任务,第二个参数是两个异步任务的执行结果,有返回值 // thenAcceptBoth,有入参,一个参数是新的异步任务,第二个参数是两个异步任务的执行结果,无返回值 // runAfterBoth,无入参,无返回值 CompletableFuture<String> taskAlone1 = CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } return "两个单独的任务需要全部完成时,这是第一个"; }); CompletableFuture<String> taskAlone2 = CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } return "这是第二个异步任务"; }); // taskAlone1.thenCombine(taskAlone2,(t1,t2)->{ // return t1+t2; // }); // // taskAlone1.thenAcceptBoth(taskAlone2,(t1,t2)->{ // System.out.println("t1+t2+\"thenAcceptBoth\" = " + t1 + t2 + "thenAcceptBoth"); // }); // // taskAlone1.runAfterBoth(taskAlone2,()->{ // System.out.println("\"runAfterBoth\" = " + "runAfterBoth"); // }); //这里还有一个thenCompose方法 他和combine的区别是 combine 会直接使用两个异步任务的返回值,而compose会返回一个completeFuture对象 //当两个异步任务有先后顺序时,可以用compose 如果两个任务是并行的,可以用combine //另外compose 可以无限的链式调用,可以将多个异步任务组合起来。 taskAlone1.thenCompose(taskAlone1Result->{ return CompletableFuture.supplyAsync(()->{ return taskAlone1Result+""; }); }); //当只需要对两个任务其中的一个执行成功即可时,可以使用applyToEither,acceptEither,runAfterEither //区别:applyToEither会将已经完成任务的执行结果作为所提供函数的参数,且该方法有返回值;acceptEither同样将已经完成任务的执行结果作为方法入参,但是无返回值;runAfterEither没有入参,也没有返回值。 // taskAlone1.applyToEither(taskAlone2, t->{ // return t.toString(); // }); // // taskAlone1.acceptEither(taskAlone2,t->{ // System.out.println("t = " + t); // }); // // taskAlone1.runAfterEither(taskAlone2,()->{ // System.out.println("\"runAfterEither\" = " + "runAfterEither"); // }); //当有更多个异步任务时,并且都需要等待他们完成时,可以使用allOf,anyOf CompletableFuture.allOf(taskAlone1, taskAlone2); String s1 = taskAlone1.get(); String s2 = taskAlone2.get(); System.out.println("s1 = " + s1); System.out.println("s2 = " + s2); CompletableFuture<Object> voidCompletableFuture = CompletableFuture.anyOf(taskAlone1, taskAlone2); Object o = voidCompletableFuture.get(); System.out.println("o = " + o); }
关于CompletableFuture的自己理解和使用
最新推荐文章于 2025-05-07 13:38:15 发布