7.26

打印 上一主题 下一主题

主题 1047|帖子 1047|积分 3141

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
CompletableFuture

1、supplyAsync、runAsync

在 Java 的 CompletableFuture 类中,supplyAsync 和 runAsync 是两个用于异步执行任务的方法。它们的重要区别在于处理返回值的方式和适用场景。下面详细介绍这两个方法。
1. supplyAsync



  • 功能: supplyAsync 方法用于异步执行一个可以返回结果的任务。
  • 返回值: 它返回一个 CompletableFuture<T>,此中 T 是通过任务盘算得到的结果。
使用场景

适用于需要盘算并返回结果的任务。
示例代码

  1. import java.util.concurrent.CompletableFuture;
  2. public class SupplyAsyncExample {
  3.     public static void main(String[] args) {
  4.         CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  5.             // 模拟一些计算
  6.             try {
  7.                 Thread.sleep(2000);
  8.             } catch (InterruptedException e) {
  9.                 Thread.currentThread().interrupt();
  10.             }
  11.             return 42; // 返回计算结果
  12.         });
  13.         // 等待结果并打印
  14.         future.thenAccept(result -> {
  15.             System.out.println("计算结果: " + result);
  16.         });
  17.         // 主线程可以继续执行其他任务
  18.         System.out.println("主线程继续执行...");
  19.         
  20.         // 等待 CompletableFuture 完成
  21.         future.join(); // 这里会阻塞直到 future 完成
  22.     }
  23. }
复制代码
2. runAsync



  • 功能: runAsync 方法用于异步执行一个不需要返回结果的任务。
  • 返回值: 它返回一个 CompletableFuture<Void>,表示任务的完成状态。
使用场景

适用于只需执行某些操作而不需要盘算返回值的任务,例如日志记载、发送通知等。
示例代码

  1. import java.util.concurrent.CompletableFuture;
  2. public class RunAsyncExample {
  3.     public static void main(String[] args) {
  4.         CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
  5.             // 模拟一些操作
  6.             try {
  7.                 Thread.sleep(2000);
  8.             } catch (InterruptedException e) {
  9.                 Thread.currentThread().interrupt();
  10.             }
  11.             System.out.println("任务完成!");
  12.         });
  13.         // 主线程可以继续执行其他任务
  14.         System.out.println("主线程继续执行...");
  15.         // 等待 CompletableFuture 完成
  16.         future.join(); // 这里会阻塞直到 future 完成
  17.     }
  18. }
复制代码
重要区别

特性supplyAsyncrunAsync返回值返回盘算结果的 CompletableFuture<T>返回 CompletableFuture<Void>用途适用于需要结果的盘算任务适用于不需要结果的执行操作示例盘算和返回一个值仅执行某些操作(如打印、更新状态) 总结



  • 使用 supplyAsync 当你需要执行一个盘算并希望得到结果时。
  • 使用 runAsync 当你只想执行一个操作而不需要返回值时。
这两个方法都可以使你的程序在多线程环境中更加高效和相应敏捷,特别适合处理 I/O 麋集型或盘算麋集型任务。通过公道使用这两个方法,可以明显提高应用程序的性能和可扩展性。
2、allOf、anyOf

allOf
CompletableFuture.allOf 是 Java 中 CompletableFuture 类的一个静态方法,它答应你组合多个 CompletableFuture 实例,并在所有这些实例都完成时举行某种操作。allOf 返回一个新的 CompletableFuture<Void>,一旦所有传入的 CompletableFuture 都完成(无论是乐成照旧失败),这个新的 CompletableFuture 就会完成。
anyOf
CompletableFuture.anyOf 方法用于组合多个 CompletableFuture 实例,直到此中一个完成(乐成或失败)。它返回一个新的 CompletableFuture,一旦任一给定的 CompletableFuture 完成,这个新的 CompletableFuture 就会完成,并且可以处理已完成的结果。
3、get

在 Java 的 CompletableFuture 中,get 方法用于获取 CompletableFuture 的盘算结果。假如 CompletableFuture 还没有完成,调用 get 方法会导致当火线程阻塞,直到盘算完成或者失败。此外,get 方法另有一个重载版本,答应你在获取结果时指定超时时间。
使用 get 方法


  • 基本用法

    • get():阻塞当火线程,直到盘算完成并返回结果。
    • get(long timeout, TimeUnit unit):阻塞当火线程,直到盘算完成、超时或者发生异常。

示例代码

下面是一个使用 CompletableFuture.allOf 和 get 方法的示例,展示怎样处理多个异步任务,并在超时环境下举行异常处理。
  1. import java.util.concurrent.CompletableFuture;
  2. import java.util.concurrent.ExecutionException;
  3. import java.util.concurrent.TimeUnit;
  4. import java.util.concurrent.TimeoutException;
  5. public class AllOfWithTimeoutExample {
  6.     public static void main(String[] args) {
  7.         // 创建多个异步任务
  8.         CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
  9.             sleep(2000); // 模拟长时间运行的任务
  10.             return "Result from Future 1";
  11.         });
  12.         
  13.         CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
  14.             sleep(1000); // 模拟较短时间的任务
  15.             return "Result from Future 2";
  16.         });
  17.         
  18.         CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
  19.             sleep(1500); // 模拟中等时间的任务
  20.             return "Result from Future 3";
  21.         });
  22.         // 使用 allOf 等待所有任务完成
  23.         CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2, future3);
  24.         try {
  25.             // 等待所有任务完成,设置超时时间为 3 秒
  26.             allOfFuture.get(3, TimeUnit.SECONDS); // 如果超时,将抛出 TimeoutException
  27.             // 获取每个 future 的结果
  28.             String result1 = future1.get();
  29.             String result2 = future2.get();
  30.             String result3 = future3.get();
  31.             // 输出结果
  32.             System.out.println("所有任务完成:");
  33.             System.out.println(result1);
  34.             System.out.println(result2);
  35.             System.out.println(result3);
  36.         } catch (TimeoutException e) {
  37.             System.out.println("操作超时,未能在规定时间内完成。");
  38.         } catch (InterruptedException e) {
  39.             Thread.currentThread().interrupt(); // 恢复中断状态
  40.             System.out.println("任务被中断。");
  41.         } catch (ExecutionException e) {
  42.             System.out.println("任务执行异常: " + e.getCause());
  43.         }
  44.     }
  45.     private static void sleep(long millis) {
  46.         try {
  47.             Thread.sleep(millis);
  48.         } catch (InterruptedException e) {
  49.             Thread.currentThread().interrupt(); // 恢复中断状态
  50.         }
  51.     }
  52. }
复制代码
4、thenApply、thenAccept、thenCompose

在 Java 的 CompletableFuture 类中,thenApply、thenAccept 和 thenCompose 是用于处理异步盘算结果的三个重要方法。它们答应你在 CompletableFuture 完成时界说后续操作,但它们的使用场景和返回范例各不雷同。下面详细介绍这三个方法。
1. thenApply



  • 功能: thenApply 方法用于对 CompletableFuture 的结果举行转换,返回一个新的结果。
  • 返回值: 返回一个新的 CompletableFuture<U>,此中 U 是通过给定的函数处理后的结果。
使用场景

适用于需要对异步盘算结果举行进一步处理并返回新结果的场景。
示例代码

  1. import java.util.concurrent.CompletableFuture;
  2. public class ThenApplyExample {
  3.     public static void main(String[] args) {
  4.         CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  5.             return 42; // 原始计算结果
  6.         });
  7.         CompletableFuture<String> transformedFuture = future.thenApply(result -> {
  8.             return "结果是: " + result; // 转换结果
  9.         });
  10.         // 打印转换后的结果
  11.         transformedFuture.thenAccept(System.out::println);
  12.     }
  13. }
复制代码
2. thenAccept



  • 功能: thenAccept 方法用于处理 CompletableFuture 的结果,但不返回任何结果。
  • 返回值: 返回一个新的 CompletableFuture<Void>,表示处理完成。
使用场景

适用于只关心异步盘算结果但不需要返回新结果的场景。
示例代码

  1. import java.util.concurrent.CompletableFuture;
  2. public class ThenAcceptExample {
  3.     public static void main(String[] args) {
  4.         CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  5.             return 42; // 原始计算结果
  6.         });
  7.         future.thenAccept(result -> {
  8.             System.out.println("结果是: " + result); // 处理结果
  9.         });
  10.     }
  11. }
复制代码
3. thenCompose



  • 功能: thenCompose 方法用于将一个 CompletableFuture 的结果转换为另一个 CompletableFuture。它通常用于处理依赖于前一个 CompletableFuture 结果的异步操作。
  • 返回值: 返回一个新的 CompletableFuture<U>,此中 U 是通过给定的函数处理后的结果。
使用场景

适用于当后续操作返回 CompletableFuture 时,需要将这些操作串联在一起的场景。
示例代码

  1. import java.util.concurrent.CompletableFuture;
  2. public class ThenComposeExample {
  3.     public static void main(String[] args) {
  4.         CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  5.             return 42; // 原始计算结果
  6.         });
  7.         CompletableFuture<String> finalFuture = future.thenCompose(result -> {
  8.             return CompletableFuture.supplyAsync(() ->
  9.                 "结果是: " + result // 依赖于前一个结果的异步操作
  10.             );
  11.         });
  12.         // 打印最终结果
  13.         finalFuture.thenAccept(System.out::println);
  14.     }
  15. }
复制代码
重要区别

方法功能返回值范例使用场景thenApply转换结果并返回新结果CompletableFuture<U>需要对结果举行处理并返回新结果的场景thenAccept处理结果但不返回任何结果CompletableFuture<Void>只关心盘算结果但不需要返回新结果的场景thenCompose将一个异步操作的结果与另一个异步操作链接在一起CompletableFuture<U>当后续操作需要依赖于前一个操作的结果并返回 CompletableFuture 的场景 总结



  • 使用 thenApply 当你需要对异步盘算的结果举行转换并返回新结果时。
  • 使用 thenAccept 当你只想处理结果而不需要返回值时。
  • 使用 thenCompose 当你需要将一个 CompletableFuture 的结果传递给另一个异步操作时。
  • thenApply 是用于将前一个任务的结果转换为另一个结果,适合用于处理结果,不启动新的异步盘算。
  • thenCompose 是用于将前一个任务的结果传递给一个返回新的 CompletableFuture 的函数,适合用于在前一个任务完成后,启动新的异步盘算。
这三个方法提供了丰富的组合本领,使得使用 CompletableFuture 举行异步编程变得更加简单和灵活。通过公道使用这些方法,可以构建复杂的异步处理流程。
5、ForkJoinPool

ForkJoinPool 是 Java 中用于并行处理任务的一个线程池,特别适合处理可拆分的任务(Fork-Join 任务)。它是 Java 并发包的一部分,提供了一个高效的任务执行框架,能够充实使用多核处理器的上风。ForkJoinPool 使用了工作窃取算法(Work Stealing),使得空闲的工作线程可以窃取任务,从而提高系统的整体性能。
重要特点


  • 可拆分任务: ForkJoinPool 特别适合处理可以被拆分成多个子任务的任务。它将大任务拆分成小任务,这些小任务可以并行执行。
  • 工作窃取算法: 在工作窃取模型中,每个线程维护一个双端队列(Deque),当任务执行完成后,线程会尝试从自己的队列中获取新的任务。假如队列为空,线程会尝试从其他线程的队列中窃取任务。
  • 简单的 API: ForkJoinPool 提供了简单的 API,可以通过 ForkJoinTask 类及其子类(如 RecursiveTask 和 RecursiveAction)来创建可拆分的任务。
总结

ForkJoinPool 是 Java 并发编程中的一个强盛工具,适用于需要并行处理的可拆分任务。它通过工作窃取算法提高了多核处理器的使用率,并提供了简单的 API,方便开辟者实现任务的分治和并行执行。通过使用 ForkJoinPool,可以明显提高盘算麋集型任务的性能。
6、总结

CompletableFuture 是 Java 8 引入的一个强盛的工具,用于支持异步编程和并行盘算。它提供了一种简便、灵活的方式来处理异步任务,支持对结果的组合、转换和异常处理。以下是 CompletableFuture 的一些重要特点和使用概述。
重要特点


  • 异步盘算:

    • CompletableFuture 答应你在背景线程中异步执行任务,避免了阻塞主线程,从而提高应用程序的相应性。

  • 结果组合:

    • 你可以将多个 CompletableFuture 组合在一起,通过 thenCombine、allOf、anyOf 等方法来处理多个异步操作的结果。

  • 链式调用:

    • CompletableFuture 支持链式调用,使得你可以将多个异步操作串联在一起,形成清晰的处理流程。常用的方法包括 thenApply、thenAccept、thenCompose 等。

  • 异常处理:

    • 提供了灵活的异常处理机制,可以使用 exceptionally、handle 和 whenComplete 方法来处理任务执行中的异常。

  • 支持回调:

    • 可以注册回调函数,在任务完成时被调用,无论是正常完成照旧异常完成。

  • 工作窃取:

    • 基于 ForkJoinPool,CompletableFuture 可以充实使用多核处理器,提高并发执行的服从。

常用方法



  • 创建任务:

    • supplyAsync(Supplier<U> supplier):异步执行并返回结果。
    • runAsync(Runnable runnable):异步执行不返回结果的任务。

  • 处理结果:

    • thenApply(Function<? super T,? extends U> fn):对结果举行转换,返回新的结果。
    • thenAccept(Consumer<? super T> action):处理结果但不返回。
    • thenCompose(Function<? super T,? extends CompletionStage<U>> fn):将结果转换为另一个 CompletableFuture。

  • 组合多个任务:

    • allOf(CompletableFuture<?>... cfs):等待所有 CompletableFuture 完成。
    • anyOf(CompletableFuture<?>... cfs):等待恣意一个 CompletableFuture 完成。

  • 异常处理:

    • exceptionally(Function<Throwable, ? extends T> fn):处理异常并提供默认值。
    • handle(BiFunction<? super T,Throwable,? extends U> fn):处理结果和异常。

示例代码

以下是一个简单的示例,展示了怎样使用 CompletableFuture 来执行异步盘算并处理结果:
  1. import java.util.concurrent.CompletableFuture;
  2. public class CompletableFutureExample {
  3.     public static void main(String[] args) {
  4.         CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
  5.             return 42; // 异步计算
  6.         });
  7.         future.thenApply(result -> {
  8.             return "结果是: " + result; // 转换结果
  9.         }).thenAccept(System.out::println) // 打印结果
  10.           .exceptionally(ex -> {
  11.               System.out.println("发生异常: " + ex.getMessage());
  12.               return null;
  13.           });
  14.     }
  15. }
复制代码
总结

CompletableFuture 提供了一种强盛而灵活的方式来处理异步编程,能够轻松地实现并发操作、结果组合和异常处理。它使得 Java 开辟者能够更方便地编写非阻塞代码,提高应用程序的性能和相应性。在当代 Java 应用中,CompletableFuture 是处理异步操作的重要工具。通过公道使用 CompletableFuture,你可以构建复杂的异步处理流程,并提高代码的可读性和可维护性。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表