代码之家  ›  专栏  ›  技术社区  ›  Sarvar Nishonboyev

如何安排任务并异步获得响应?

  •  1
  • Sarvar Nishonboyev  · 技术社区  · 6 年前

    我不知道我是否使用了正确的标题,但我将尝试在下面解释这个问题。 我使用以下方法检查外部服务的付款状态:

    @Autowired
    PaymentService paymentService; 
    
    public void checkPaymentStatus(Payment p){
       // sending 
       String status = paymentService.getPaymentStatus(p.getId());
    }
    

    它在主线程中工作,每秒可能有数百个请求,因此我决定使用CompletableFuture在不同的线程中异步运行任务。

    @Autowired
    PaymentService paymentService; 
    
    public void checkPaymentStatus(Payment p){
       // sending 
       CompletableFuture<Response> status = paymentService.getPaymentStatus(p.getId());
    }
    

    PaymentService。班

    @Service
    public class PaymentService{
    
    private final RestTemplate restTemplate;
    
      @Async
      public CompletableFuture<Response> getPaymentStatus(long id){
        Response results = restTemplate.getForObject(url, Response.class);
        return CompletableFuture.completedFuture(results);
      }
    }
    

    配置

    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("payment-service-");
        executor.initialize();
        return executor;
    }
    

    它工作得很好,但我还有另一个任务。每个请求在发送到外部服务之前必须等待30秒。

    如何解决这个问题?

    更新:

    更新: 在这种方法中,我可能使用线程睡眠,但这不是正确的解决方案,因为它会阻塞线程30秒,下一个任务可能会在60秒后运行,等等。

    @Async
      public CompletableFuture<Response> getPaymentStatus(long id){
       // I might use Thread sleep here, but it is not the correct solution as it blocks the Thread for 30 seconds and next task might run after 60 secs, etc.
        Response results = restTemplate.getForObject(url, Response.class);
        return CompletableFuture.completedFuture(results);
      }
    
    0 回复  |  直到 6 年前