嗨,我是 java 多线程的新手。有人可以帮我解决这个问题吗:
我的服务:
@Async
public List<String> doSomething(int a){
//Do something
return list;
}
Springboot应用:
@SpringBootApplication
@EnableAsync
public class Test {
public static void main(String[] args) {
SpringApplication.run(Test.class, args);
}
}
异步配置:
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name ="taskExecutor")
public Executor taskExecutor(){
ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("userThread-");
executor.initialize();
return executor;
}
}
控制器:
@RestController
public class Controller{
@Autowired
private Service service;
@GetMapping("test")
public List<String> getAll(){
return service.doSomething(1);
}
}
当我点击邮递员的此获取请求时,它在响应中显示为空白。我知道我的调用是异步进行的,甚至在调用我的方法之前响应就会返回。有没有办法通过更改我的邮递员或 Spring Boot 应用程序中的某些设置来查看此响应
如果你想异步处理请求,但又希望API客户端在处理完成后收到响应,这样从客户端的角度来看,请求处理仍然看起来像同步的,关键是使用Servlet3异步处理功能。
您无需使用
@Aysnc
将其配置为在服务级别异步执行。相反,将控制器方法配置为返回 CompletableFuture
。在幕后,它将触发 Servlet3 的异步请求处理,该处理将在接收请求的 HTTP 线程之外的另一个线程中处理该请求。
所以你的代码应该类似于:
public class Service {
//No need to add @Async
public List<String> doSomething(int a){
return list;
}
}
@RestController
public class Controller{
@Autowired
private Service service;
@GetMapping("test")
public CompletableFuture<List<String>> getAll(){
return CompletableFuture.supplyAsync(()->service.doSomething(1));
}
}
关于 spring-mvc 支持的 Servlet3 异步请求处理的详细内容,可以参考从this开始的这个博客系列。
如果您想使用异步,我会将您的单个请求拆分为所谓的“启动任务”和“获取任务结果”请求。您的应用程序返回“启动任务”请求的“请求 ID”。然后在执行“获取任务结果”时使用“请求 ID”。这样的场景是批处理任务中常见的方式。如果您使用 Spring,您可能会对研究 Spring Batch 框架感兴趣,该框架具有启动/停止/重新启动作业功能等。
您可以返回CompletableFuture。当 CompleteableFuture 完成时,您将收到 http 响应。
服务:
@Async
public CompletableFuture<List<String>> doSomething() {
return CompletableFuture.completedFuture(Arrays.asList("1", "2", "3"));
}
控制器:
@GetMapping("test")
public CompletableFuture<List<String>> getAll(){
return service.doSomething();
}