Java 线程提交一个任务,不要等待spring中的完成

Java 线程提交一个任务,不要等待spring中的完成,java,spring,multithreading,Java,Spring,Multithreading,我正在编写一个服务,其中我想公开一个端点,该端点将调用另一个服务,如果服务调用成功,那么我想将结果发送回UI/调用应用程序 在发送回响应之前,我希望执行/提交一个任务,该任务应在后台运行,我的调用不应依赖于此任务的成功或失败 在返回响应之前,我希望执行以下操作- executorService.execute(object); 这不应该是阻塞调用 任何建议Spring异步方法都是在评论中建议的方法 一些警告: 异步方法可以有不同的返回类型,它们确实可以返回CompletableFuture,但

我正在编写一个服务,其中我想公开一个端点,该端点将调用另一个服务,如果服务调用成功,那么我想将结果发送回UI/调用应用程序

在发送回响应之前,我希望执行/提交一个任务,该任务应在后台运行,我的调用不应依赖于此任务的成功或失败

在返回响应之前,我希望执行以下操作-

executorService.execute(object);
这不应该是阻塞调用


任何建议

Spring异步方法都是在评论中建议的方法

一些警告:

  • 异步方法可以有不同的返回类型,它们确实可以返回CompletableFuture,但如果您从某个后台进程调用它们,并希望等待/检查它们的执行状态,或者在future准备就绪时执行其他操作,则会出现这种情况。在你的情况下,你似乎想要“开火然后忘记”的行为。因此,您应该为
    @Async
    带注释的方法使用
    void
    返回类型

  • 确保放置
    @EnableAsync
    。在这种情况下,它的工作方式是用某种代理将具有
    @Async
    方法的bean包装起来,因此代理实际上被注入到您的服务中。因此,
    @EnableAsync
    启用此代理生成机制。您可以在调试器中验证这种情况,并检查注入的引用对象的实际类型

  • 考虑自定义任务执行器,以确保使用符合需要的执行器运行异步方法。例如,您可能不希望每次调用异步方法都会产生一个新线程(并且有一个执行器的行为类似于此)。例如,您可以阅读有关各种执行者的信息

  • 更新

    代码方面,您应该执行以下操作:

    public class MyAsyncHandler {
    
        @Async
        public void doAsyncJob(...) {
          ...
        }
    }
    
    @Service 
    public class MyService {
      @Autowired // or autowired constructor
      private MyAsyncHandler asyncHandler;
    
      public Result doMyMainJob(params) {
    
         dao.saveInDB();
         // do other synchronous stuff
         Result res = prepareResult();
         asyncHandler.doAsyncJob(); // this returns immediately
         return res;
      }
    }
    

    正如在评论中所建议的那样,Spring异步方法是实现这一点的方法

    一些警告:

  • 异步方法可以有不同的返回类型,它们确实可以返回CompletableFuture,但如果您从某个后台进程调用它们,并希望等待/检查它们的执行状态,或者在future准备就绪时执行其他操作,则会出现这种情况。在你的情况下,你似乎想要“开火然后忘记”的行为。因此,您应该为
    @Async
    带注释的方法使用
    void
    返回类型

  • 确保放置
    @EnableAsync
    。在这种情况下,它的工作方式是用某种代理将具有
    @Async
    方法的bean包装起来,因此代理实际上被注入到您的服务中。因此,
    @EnableAsync
    启用此代理生成机制。您可以在调试器中验证这种情况,并检查注入的引用对象的实际类型

  • 考虑自定义任务执行器,以确保使用符合需要的执行器运行异步方法。例如,您可能不希望每次调用异步方法都会产生一个新线程(并且有一个执行器的行为类似于此)。例如,您可以阅读有关各种执行者的信息

  • 更新

    代码方面,您应该执行以下操作:

    public class MyAsyncHandler {
    
        @Async
        public void doAsyncJob(...) {
          ...
        }
    }
    
    @Service 
    public class MyService {
      @Autowired // or autowired constructor
      private MyAsyncHandler asyncHandler;
    
      public Result doMyMainJob(params) {
    
         dao.saveInDB();
         // do other synchronous stuff
         Result res = prepareResult();
         asyncHandler.doAsyncJob(); // this returns immediately
         return res;
      }
    }
    

    看看Spring异步方法:@Async public CompletableFuture findUser(字符串用户)抛出中断异常{logger.info(“查找”+user);字符串url=String.format(“”,user);用户结果=restemplate.getForObject(url,user.class);//人工延迟1s用于演示Thread.sleep(1000L);返回CompletableFuture.completedFuture(结果);}。这没有帮助,因为它返回的中间结果查看Spring异步方法:@Async public CompletableFuture findUser(字符串用户)抛出中断异常{logger.info(“查找”+user);字符串url=String.format(“”,user);用户结果=restTemplate.getForObject(url,user.class);//人工延迟1s用于演示Thread.sleep(1000L);返回CompletableFuture.completedFuture(结果);}。这是没有帮助的,因为它返回的中间结果0是的,我希望结果返回到ui,然后再做一个。。这将是火灾和伪造,所以我们可以将excutor.excute()提交给我尝试过但可完成的asyn方法future.runAsync(pre…);但是它没有将executorService作为objectAsync方法来封装与执行器的工作(您也可以直接与执行器一起工作,但这样您就错过了“异步”很好。我已经更新了答案,让您了解代码的外观。我建议您先尝试一下,然后自己检查结果。谢谢您的回答。这很有帮助。。只有一件事-@Async public void doAsyncJob(…){…}。这将spwan一个新线程假设我想通过spwaing 5线程来完成我的任务…thn.private static final ExecutorService ExecutorService=Executors.newFixedThreadPool(10);@Async public void doAsyncJob(…){ExecutorService.execute(pre);}.那么你看到这种方法有什么缺陷吗???它不会产生新的线程,而是重复使用你选择的线程池(你知道,每次产生新线程都很昂贵)但是,为此,您应该配置任务执行器bean。您应该阅读有关异步的更深入的文档。同样,这与您自己使用执行器是一样的,但是使用@async aproach0时代码更干净。是的,我希望结果返回到ui,然后再生成一个。这将是激发和伪造的。我们可以提交excut吗或者.excute()到我尝试过的asyn方法,但是CompletableFuture.runAsync(pre…);但是它不接受executorService,因为objectAsync方法将工作封装在执行器中(您也可以直接使用执行器,但是