当前位置: 首页 > 知识库问答 >
问题:

CompletableFuture thenApplyAsync与thenCompose及其用例[重复]

欧阳何平
2023-03-14
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
    System.out.println(Thread.currentThread().getName() + " Printing hello");
    return "Hello";
}).thenCompose((String s) -> {
  return CompletableFuture.supplyAsync(() -> {
      System.out.println(Thread.currentThread().getName() + " Adding abc");
      return "abc "+s;});
}).thenApplyAsync((String s) -> {
    System.out.println(Thread.currentThread().getName() + " Adding world");
    return s + " World";
}).thenApplyAsync((String s) -> {
    System.out.println(Thread.currentThread().getName() + " Adding name");
    if (false) {
       throw new RuntimeException("Oh no exception");
    }
    return s + " player!";
}).handle((String s, Throwable t) -> {
    System.out.println(s != null ? s : "BLANK");
    System.out.println(t != null ? t.getMessage() : "BLANK Exception");
    return s != null ? s : t.getMessage();
});

我浏览了这个链接,但它讨论的是thenApply,这有点不同:CompletableFuture thenApply vs thenCompose

共有1个答案

施季
2023-03-14

当操作返回CompletionStage时,可以使用thencompose,当操作不返回CompletionStage时,可以使用thenapply。->这是在enapply vs encompose中

但是,CompletionStage接口的Async变体有细微的区别和罕见的用例。

让我们考虑一下这个例子:

import java.util.concurrent.CompletableFuture;

public class Futures {

    public static void main(String[] args) throws InterruptedException {

        CompletableFuture<Void> c = CompletableFuture.runAsync(() -> {

            System.out.println("run1: " + Thread.currentThread().getId());
        });

        c.whenComplete((r, t) -> {
            System.out.println("I'm completed");
        });

        c.thenCompose(__ -> {
            System.out.println("thenCompose1: " + Thread.currentThread().getId());
            return CompletableFuture.runAsync(() -> {
                System.out.println("run2: " + Thread.currentThread().getId());
            });
        }).thenRunAsync(() -> {
            System.out.println("RunAsync1: " + Thread.currentThread().getId());
        });

        Thread.sleep(5000);

        System.out.println("Finished");
    }
}

它输出类似于:

run1: 11
thenCompose1: 11
run2: 12
I'm completed
RunAsync1: 11
Finished
static CompletionStage<String> insert(Object database) {
    throw new UnsupportedOperationException();
}

static CompletionStage<Object> get(String id) {
    throw new UnsupportedOperationException();
}

public static void main(String[] args) throws InterruptedException {

    Object db = new Object(); // pretend this connects to a database
    CompletionStage<Object> recordInserted = insert(db).thenCompose(id -> get(id));
}

然后,您将使用ThenApplyAsync启动发送电子邮件逻辑,因为它对您的系统并不重要。用户总是可以回去说“再给我发一封电子邮件”

static CompletionStage<String> register(String username) {
    throw new UnsupportedOperationException();
}

static void sendConfirmationEmail(String username) {
    throw new UnsupportedOperationException();
}

public static void main(String[] args) throws InterruptedException {

    register("user").thenAcceptAsync(username -> sendConfirmationEmail(username));

}

在这里,当注册完成时,您的系统会响应,但它不会等待电子邮件发送,从而提高了您系统的响应能力。

到目前为止,我发现的Async变体的用例很少,但它们确实存在。

 类似资料:
  • 问题内容: 我无法理解)和之间的区别。 那么,有人可以提供有效的用例吗? 从Java文档中: 返回一个新值,当此阶段正常完成时,将使用该阶段的结果作为所提供函数的参数来执行该操作。 返回一个新值,当此阶段正常完成时,将以该阶段作为所提供函数的参数来执行此操作。 我得到扩展的CompletionStage 的第二个参数,而没有扩展。 有人可以提供一个例子,说明我必须在什么情况下使用以及何时使用? 问

  • 本文向大家介绍ICONFONT使用及其利与弊?相关面试题,主要包含被问及ICONFONT使用及其利与弊?时的应答技巧和注意事项,需要的朋友参考一下 把一些零散的icon做成字体。我们调用文字的时候,渲染出来的就是icon图像,这样的显示就是iconfont(字体图标) 好处: iconfont图像放大后,不会失真。 iconfont节省流量 iconfont在颜色变幻方面很简单 缺点: iconf

  • 本文向大家介绍java 重载(overload)与重写(override)详解及实例,包括了java 重载(overload)与重写(override)详解及实例的使用技巧和注意事项,需要的朋友参考一下  很多同学对于overload和override傻傻分不清楚,建议不要死记硬背概念性的知识,要理解着去记忆。        先给出我的定义:     overload(重载):在同一类或者有着继承

  • 我搞不清)和之间的区别。 那么,有人能提供一个有效的用例吗? 从Java文档中: 返回一个新的,当此阶段正常完成时,将以此阶段的结果作为所提供函数的参数执行该。 返回一个新的,当此阶段正常完成时,将以此阶段作为所提供函数的参数执行该。 我发现的第二个参数扩展了CompletionStage,而没有扩展CompletionStage。 谁能提供一个例子,在什么情况下我必须使用以及什么时候使用?

  • 本文向大家介绍Java toUpperCase()方法及其示例,包括了Java toUpperCase()方法及其示例的使用技巧和注意事项,需要的朋友参考一下 UpperCase()方法将所有字符转换为大写字母。此方法有两个变体。第一个变体使用给定Locale的规则将此String中的所有字符转换为大写。这等效于调用toUpperCase(Locale.getDefault())。 示例 现在让我

  • 本文向大家介绍C / C ++中的mbrtoc16()及其示例,包括了C / C ++中的mbrtoc16()及其示例的使用技巧和注意事项,需要的朋友参考一下 在本文中,我们将讨论C ++ STL中std::mbrtoc16()函数的工作,语法和示例。 什么是std::mbrtoc16()? std::mbrtoc16()函数是C ++ STL中的内置函数,在<cuchar>头文件中定义。此函数用