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

带多线程的Spring引导异步

喻珂
2023-03-14

我有一个spring boot微服务,我们在其中调用多个服务(比如服务a和服务B)。我试图根据某些条件在多个线程上异步调用这两个服务,一旦处理完成,我想合并服务A和服务B的响应。

我知道我们可以使用@Async异步运行一个进程,并使用ExecutorService为一个服务启动多个线程。

但是我不确定如何把所有的东西放在一起。所以在这里寻找任何建议?

              @Async
              Service A(thread1,thread2) \
MicroService /                             (Merge from Response of ServiceA and ServiceB)
             \ @Async
              Service B(thread1,thread2) /

我知道这在上面主要是理论上解释的,但我尝试了跟随/浏览多个网站,但大多数文章要么解释了Aync或Multithread,但不确定如何在多个线程中等待和运行Async中的两个进程,并在这两个服务调用完成后继续执行!

感谢任何建议或线索!TIA:)

共有2个答案

戚澄邈
2023-03-14

您可以展望java的完整未来。ComplitableFuture允许合并多个异步任务(也是CompletableFuture),并等待所有CompletableFuture的结果。我不确定它是否完全适合你的情况,但它可能会有所帮助。https://www.baeldung.com/java-completablefuture#Multiple

刁冠宇
2023-03-14

您需要使用spring的AsyncResult类包装结果,然后使用其方法。completable()返回CompletableFuture对象。

合并未来对象时,使用CompletableFuture.thenCompose()和CompletableFuture.thenApply()方法合并数据,如下所示:

CompletableFuture<Integer> result = futureData1.thenCompose(fd1Value -> 
                futureData2.thenApply(fd2Value -> 
                        merge(fd1Value, fd2Value)));

以下是一个基本示例:

用EnableSync注释Spring boot主类

@SpringBootApplication
@EnableAsync
public class StackOverflowApplication {

    public static void main(String[] args) {
        SpringApplication.run(StackOverflowApplication.class, args);
    }

}

创建一个将返回CompletableFuture的示例服务

A服务。Java语言

@Service
public class Aservice {

    @Async
    public CompletableFuture<Integer> getData() throws InterruptedException {
        Thread.sleep(3000); // sleep for 3 sec
        return new AsyncResult<Integer>(2).completable(); // wrap integer 2
    }
}

b服务。Java语言

@Service
public class Bservice {

    @Async
    public CompletableFuture<Integer> getData() throws InterruptedException {
        Thread.sleep(2000); // sleep for 2 sec
        return new AsyncResult<Integer>(1).completable(); // wrap integer 1
    }
}

创建另一个将合并其他两个服务数据的服务

结果服务。Java语言

@Service
public class ResultService {

    @Autowired
    private Aservice aservice;
    @Autowired
    private Bservice bservice;

    public CompletableFuture<Integer> mergeResult() throws InterruptedException, ExecutionException {
        CompletableFuture<Integer> futureData1 = aservice.getData();
        CompletableFuture<Integer> futureData2 = bservice.getData();

        // Merge futures from Aservice and Bservice
        return futureData1.thenCompose(
            fd1Value -> futureData2.thenApply(fd2Value -> fd1Value + fd2Value));
    }
}

创建用于测试的示例控制器

结果控制器。Java语言

@RestController
public class ResultController {

    @Autowired
    private ResultService resultService;

    @GetMapping("/result")
    CompletableFuture<Integer> getResult() throws InterruptedException, ExecutionException {
        return resultService.mergeResult();
    }

}
 类似资料:
  • 我正计划开发一个多租户应用程序,目前我只是在研究网络上的不同实现,以了解实现此类任务所需的需求。HibernateSpring引导是我计划使用的技术。 从我的阅读资料来看,所有不同的教程都使用相同的方法,即在配置文件中声明数据源,以便在应用程序启动时启动会话工厂,但我真的希望有一个更高级别的应用程序,在那里我可以动态添加租户并输入他们的数据源信息。这样应用程序就可以获得新租户的信息,而无需触摸配置

  • 我有一个多步骤Spring Batch作业,在其中一个步骤中,我为在阅读器中读取的数据创建Lucene索引,以便后续步骤可以在该Lucene索引中搜索。 基于中读取的数据,我将索引分散到几个单独的目录中。 如果我指定Step Task Executor为,只要索引总是写入不同的目录,我就不会遇到任何问题,但有时会出现锁定异常。我猜,两个线程试图写入同一个索引。 如果我删除了,我不会遇到任何问题,但

  • 我有一个简单的Spring Boot应用程序(在STS中创建为“starter project”)。我使用log4j2进行日志记录 无论我尝试什么,我都没有在交换中看到任何消息;我只在控制台中看到它们。 我成功地将log4j(1)与旧版本的org.springframework.amqp:spring-rabbit:1.5.6 AmqpAppender(org.springframework.am

  • 我正在使用spring 和< code>HTTP post请求,逐行获取数据,然后将数据发送到API的HTTP请求中,这对我来说很好,但这里我使用的是大量数据,所以我必须使用多线程,但我是java和spring的新手,我如何实现使用10个线程,每个线程每次并行读取1k的数据? 我读过关于10个线程的多线程,其中每个线程每次读取1k行,我的数据库中有大约1000万条记录 访问DataJpaAppli

  • 当线程停止时,关闭Spring引导的正确方法是什么?我不应该使用Spring中的吗? 谢谢!

  • 我有一个Spring引导应用程序,在控制器中,我有一个注入的服务类,并且有一个来自该服务类的方法从一个线程调用。我的应用程序有一个索引页面,用户可以设置值并开始一些计算,设置值发生在服务类中,要开始计算,用户点击一个按钮,将启动控制器中调用服务类中的方法的线程。结果将显示在不同的页面,该页面有一个按钮,该按钮返回到索引页面,以开始不同值的ne计算。 我需要一个新的注入bean,当我在计算后返回到索