自适应网站优点缺点网站模块化
自适应网站优点缺点,网站模块化,网站建设成都创新互联,怎么通过互联网做一个服务的网站一、前言 CompletableFuture 是 Java 8 引入的一个功能强大的类#xff0c;用于异步编程。它表示一个可能尚未完成的计算的结果#xff0c;你可以对其添加回调函数来在计算完成时执行某些操作。在 Spring Boot 应用中#xff0c;CompletableFuture 可以用于提高应用的响应性…一、前言 CompletableFuture 是 Java 8 引入的一个功能强大的类用于异步编程。它表示一个可能尚未完成的计算的结果你可以对其添加回调函数来在计算完成时执行某些操作。在 Spring Boot 应用中CompletableFuture 可以用于提高应用的响应性和吞吐量。
二、为什么使用异步编程 场景描述进入用户个人中心调用接口。接口需要返回用户基础信息、用户积分、用户等级等假设用户基础信息查询耗时300ms查询用户积分、用户等级分别耗时200ms那么接口返回就需要700ms了。那么我们如何去优化呢 如果采用异步多线程并行形式接口将以用户基础信息查询耗时300ms最慢的为主接口性能提升一倍查询任务越多则其性能提升越大
三、异步编程介绍 在Java中Callable、Runnable、Future和CompletableFuture是用于处理并发编程的重要接口和类。它们各自有不同的用途和特性下面是对它们的简要介绍
1. Callable Callable是一个接口用于定义返回结果或抛出异常的任务。它类似于Runnable但Runnable没有返回值且不能抛出受检异常。Callable接口中定义了一个call()方法该方法可以返回一个值并且可以抛出一个受检异常。
2. Runnable Runnable是一个接口用于定义没有返回值且不抛出受检异常的任务。它只有一个run()方法用于执行任务的代码。通常Runnable对象会被传递给Thread对象的构造函数来创建新线程。
3. Future Future是一个接口用于表示异步计算的结果。它是Java并发包java.util.concurrent的一部分。当你提交一个Callable任务给ExecutorService时它会返回一个Future对象该对象表示异步计算的结果。你可以使用Future的get()方法来等待计算完成并获取结果或者使用isDone()方法来检查计算是否完成。
4. CompletableFuture CompletableFuture是Java 8中引入的一个类实现了Future和CompletionStage接口。它提供了函数式编程的能力来处理异步编程并允许你链式地组合多个异步操作。CompletableFuture提供了许多方法如thenApply(), thenAccept(), thenCompose(), exceptionally()等这些方法允许你定义当异步操作完成时应该执行的操作。 CompletableFuture相对于Future的优势在于它提供了更丰富的API来处理异步计算的结果并支持链式调用和组合多个异步操作。这使得编写异步代码更加简洁和直观。
四、CompletableFuture中的函数式编程 在CompletableFuture类中的方法很多都是Function函数式接口方法为入参所以我们先要有一定的认识。 SupplierU // 生产者没有入参有返回结果ConsumerT // 消费者有入参但是没有返回结果FunctionT,U// 函数有入参又有返回结果五、CompletableFuture核心方法介绍
5.1. 创建异步任务 supplyAsync: 异步执行一个给定的Supplier函数并返回一个新的CompletableFuture其结果由Supplier决定。 CompletableFutureVoid/Type supplyAsync(SupplierU supplier)CompletableFutureVoid/Type supplyAsync(SupplierU supplier, Executor executor)允许指定执行器。runAsync: 异步执行一个Runnable任务由于没有返回值所以返回的CompletableFuture类型为Void。 CompletableFutureVoid runAsync(Runnable runnable)CompletableFutureVoid runAsync(Runnable runnable, Executor executor)允许指定执行器。5.1.1. 代码示例
supplyAsync
CompletableFutureStringfutureCompletableFuture.supplyAsync(()-{System.out.println(compute test);return test;
});String result future.join();System.out.println(get result: result);runAsync
CompletableFutureVoid future CompletableFuture.runAsync(()-{System.out.println(compute test);
});System.out.println(get result: future.join());指定线程池
ExecutorService executorService new ThreadPoolExecutor(2, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue(100));CompletableFutureUser task1 CompletableFuture.supplyAsync(()-{User userInfo userService.getUserInfo(1);return userInfo;
}, executorService);// 获取结果
User user task1.get();5.2. 流式连接函数介绍 流式连接函数也称为组合函数允许你以函数式编程的方式组合和链接多个异步操作。 假如我有两个任务任务2需要等任务1执行完成后拿到任务1中的结果作为任务2的参数这时候就需要用到流式连接函数。
①. thenApply 和 thenApplyAsync thenApply: 当前CompletableFuture计算完成时应用给定的函数到其结果上并返回表示该结果的新的CompletableFuture。 thenApplyAsync: 与thenApply类似但异步执行给定的函数。
②. thenAccept 和 thenAcceptAsync thenAccept: 当当前CompletableFuture计算完成时执行给定的动作到其结果上然后返回void。 thenAcceptAsync: 与thenAccept类似但异步执行给定的动作。
③. thenRun 和 thenRunAsync thenRun: 当当前CompletableFuture计算完成时执行给定的动作不关注其结果。 thenRunAsync: 与thenRun类似但异步执行给定的动作。
④. thenCombine 和 thenCombineAsync thenCombine: 接收另一个CompletableFuture并返回一个新的CompletableFuture该CompletableFuture在当前CompletableFuture和另一个CompletableFuture都完成计算后使用它们的结果来计算值。 thenCombineAsync: 与thenCombine类似但异步执行给定的函数。
⑤. thenCompose 和 thenComposeAsync thenCompose: 当当前CompletableFuture计算完成时应用给定的函数到其结果上该函数返回一个新的CompletableFuture并返回表示该新CompletableFuture的结果的CompletableFuture。 thenComposeAsync: 与thenCompose类似但异步执行给定的函数。
⑥. whenComplete 和 whenCompleteAsync whenComplete: 当当前CompletableFuture正常完成或出现异常时执行给定的动作。动作有两个参数结果如果操作正常完成或异常如果抛出异常以及一个表示该CompletableFuture的Throwable如果操作抛出异常则为null。 whenCompleteAsync: 与whenComplete类似但异步执行给定的动作。
⑦. handle 和 handleAsync handle: 当当前CompletableFuture正常完成或出现异常时应用给定的函数到其结果或异常上并返回一个新的CompletableFuture其结果是函数的结果。 handleAsync: 与handle类似但异步执行给定的函数。 注意带Async后缀的函数表示需要连接的后置任务会被单独提交到线程池中从而相对前置任务来说是异步运行的。除此之外两者没有其他区别。 在使用Async后缀的方法时你可以提供一个Executor作为可选参数来指定异步操作应在哪个线程上执行。如果未提供则使用ForkJoinPool.commonPool()。
5.3. 流式连接核心函数代码示例
1. thenApply / thenAccept / thenRun 这组函数主要用于连接前后有依赖的任务链。这里将thenApply / thenAccept / thenRun放在一起讲因为这几个连接函数之间的唯一区别是提交的任务类型不一样。
区别如下 1.thenApply提交的任务类型需遵从Function签名也就是有入参和返回值其中入参为前置任务的结果。 2.thenAccept提交的任务类型需遵从Consumer签名也就是有入参但是没有返回值其中入参为前置任务的结果。 3.thenRun提交的任务类型需遵从Runnable签名即没有入参也没有返回值。
代码示例
CompletableFutureInteger future1 CompletableFuture.supplyAsync(()-{System.out.println(compute 1);return 1;
});CompletableFutureInteger future2 future1.thenApply((p)-{System.out.println(compute 2);return p10;
});
System.out.println(result: future2.join());注意的是通过thenApply / thenAccept / thenRun连接的任务当且仅当前置任务计算完成时才会开始后置任务的计算。
应用场景总结 1. thenApply当需要在异步操作的结果上执行额外的计算或转换时使用 thenApply。 2. thenAccept当只需要消费异步操作的结果而不关心新的结果或执行额外的任务时使用 thenAccept。 3. thenRun当需要在异步操作完成后执行一个不依赖于其结果的任务时使用 thenRun。
2. thenCombine thenCombine最大的不同是连接任务可以是一个独立的CompletableFuture从而允许前后连接的两个任务可以并行执行后置任务不需要等待前置任务执行完成最后当两个任务均完成时再将其结果同时传递给下游处理任务从而得到最终结果
代码示例 假设我们有两个异步任务一个用于获取用户的名字nameFuture另一个用于获取用户的年龄ageFuture。我们希望当这两个任务都完成后将它们的结果组合成一个字符串如 “Name: John, Age: 30”。 CompletableFutureString nameFuture CompletableFuture.supplyAsync(() - getUserName());
CompletableFutureInteger ageFuture CompletableFuture.supplyAsync(() - getUserAge()); CompletableFutureString combinedFuture nameFuture.thenCombine(ageFuture, (name, age) - Name: name , Age: age
); combinedFuture.thenAccept(System.out::println);
// 输出类似 Name: John, Age: 30thenAcceptBoth、thenAcceptBothAsync、runAfterBoth、runAfterBothAsync的作用与thenConbime类似区别如下 1. thenAcceptBoth 和 thenAcceptBothAsync 用于处理两个异步操作的结果但不返回新的结果。 2. runAfterBoth 和 runAfterBothAsync 也用于处理两个异步操作的完成但不关注它们的结果。 3. thenCombine 用于处理两个异步操作的结果并返回一个新的结果。
3. thenCompose thenCompose 的应用场景主要涉及到需要基于一个异步任务的结果来发起另一个异步任务的情况。它允许你将多个异步操作链接在一起并以前一个操作的结果作为后一个操作的输入。
代码示例
如果使用thenApply实现如下CompletableFutureInteger future1 CompletableFuture.supplyAsync(()-{System.out.println(compute 1);return 1;
});
CompletableFutureCompletableFutureInteger future2 future1.thenApply((r)-CompletableFuture.supplyAsync(()-r10));
System.out.println(future2.join().join());当连接的任务越多时代码会变得越来越复杂嵌套获取层级也越来越深。使用thenCompose
CompletableFutureInteger future1 CompletableFuture.supplyAsync(()-{System.out.println(compute 1);return 1;
});
CompletableFutureInteger future2 future1.thenCompose((r)-CompletableFuture.supplyAsync(()-r10));
System.out.println(future2.join());4. whenComplete whenComplete主要用于注入任务完成时的回调通知逻辑。这个解决了传统future在任务完成时无法主动发起通知的问题。前置任务会将计算结果或者抛出的异常作为入参传递给回调通知函数。
代码示例
CompletableFutureString future CompletableFuture.supplyAsync(() - { // 模拟从数据库读取数据的异步操作 return Data from database;
}); future.whenComplete((result, exception) - { if (exception null) { // 操作成功记录成功日志 System.out.println(Operation succeeded. Result: result); } else { // 操作失败记录异常日志 System.err.println(Operation failed with exception: exception.getMessage()); } // 在这里还可以执行其他与结果无关的操作如清理资源、发送通知等
});5. handle handle与whenComplete的作用有些类似但是handle接收的处理函数有返回值而且返回值会影响最终获取的计算结果。
代码示例
CompletableFutureInteger future1 CompletableFuture.supplyAsync(()-{System.out.println(compute 1);return 1;
});CompletableFutureInteger future2 future1.handle((r, e)-{if(e ! null){System.out.println(compute failed!);return r;} else {System.out.println(received result is r);return r 10;}
});System.out.println(result: future2.join());六、CompletableFuture中获取异步任务结果介绍
异步任务执行完成之后需要获取结果有如下一些方法 1. allOf 方法用于等待多个 CompletableFuture 任务全部完成。它接受一个 CompletableFuture 数组或列表作为参数并返回一个新的 CompletableFuture。这个新的 CompletableFuture 会在所有给定的 CompletableFuture 都完成时完成但它不包含任何原始任务的结果。 2. anyOf 方法与 allOf 类似但它只等待给定的 CompletableFuture 中的一个完成。它同样接受一个 CompletableFuture 数组或列表作为参数并返回一个新的 CompletableFuture。这个新的 CompletableFuture 会在任何一个给定的 CompletableFuture 完成时完成但它不包含任何原始任务的结果。 3. join 方法用于等待 CompletableFuture 完成并返回其结果如果可用。如果 CompletableFuture 尚未完成则 join 会阻塞当前线程直到它完成。如果 CompletableFuture 异常完成则 join 会抛出与异常完成相对应的异常。 4. get 方法与 join 类似也用于等待 CompletableFuture 完成并返回其结果。但是get 方法可以接收一个可选的超时参数和一个时间单位以便在指定的时间内等待 CompletableFuture 完成。如果 CompletableFuture 在指定的时间内没有完成则 get 方法会抛出 TimeoutException。另外如果 CompletableFuture 异常完成则 get 方法会抛出 ExecutionException包装了原始异常或 InterruptedException如果当前线程在等待时被中断。 以上就是对CompletableFuture的一些详细介绍以及一些常用api的代码示例希望对你在项目进行性能方面的代码优化中有一定的作用。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/92345.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!