Java 控制器线程正在等待异步方法响应
我是spring boot的新手,想了解更多关于DeferredResult和@Async方法的信息。我在controller中创建了一个方法,如下所示,效果很好Java 控制器线程正在等待异步方法响应,java,spring,spring-boot,Java,Spring,Spring Boot,我是spring boot的新手,想了解更多关于DeferredResult和@Async方法的信息。我在controller中创建了一个方法,如下所示,效果很好 @GetMapping("/temp/{id}") public DeferredResult<ResponseEntity<?>> findByIdTemp(@PathVariable Long id) throws InterruptedException { System.o
@GetMapping("/temp/{id}")
public DeferredResult<ResponseEntity<?>> findByIdTemp(@PathVariable Long id) throws InterruptedException {
System.out.println("Request received : "+Thread.currentThread().getName());
final DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>();
ForkJoinPool.commonPool().submit(() -> {
System.out.println("Processing in separate thread");
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
}
deferredResult.setResult(ResponseEntity.ok("ok"));
});
System.out.println("Thread freed : " +Thread.currentThread().getName());
return deferredResult;
}
然后,我在服务类中创建了@Async方法,并在配置类中启用了Async
@Configuration
@EnableAsync
public class ThreadPoolConfiguration {
@Autowired
private ExecutorConfiguration configuration;
@Bean(name = "threadPool")
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
threadPool.setCorePoolSize(configuration.getDnCallBackPoolSize());
return threadPool;
}
}
控制器方法似乎正在等待服务方法的响应。有谁能告诉我如何正确地使用DeferredResult和@Async方法吗
控制器方法似乎正在等待服务方法的响应
是,控制器方法正在等待来自productService
的响应,因为dnCallBackPool
中的@Async
线程只负责执行productService
中的getResult()
方法
但是try-catch
块中的代码由web容器线程执行(例如http-nio-8080-exec-1
)
因此productService.getResult()
上的Future
对象调用是一个阻塞调用,如果当前线程应该等到@Async
线程完成其进程并返回结果
如有必要,等待计算完成,然后检索其结果
因此,在控制器方法末尾的Future
对象上执行get()
,以便两个方法并行执行,下面是一个示例
控制器:
@GetMapping("/temp/{id}")
public DeferredResult<ResponseEntity<?>> findByIdTemp(@PathVariable Long id) {
System.out.println("Request received : "+Thread.currentThread().getName());
final DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>();
Future<String> future = productService.getResult(); //Async call to service method
System.out.println("Current Thread Execution: " +Thread.currentThread().getName()); // Execute parallely and print this line immediately
ResponseDTO responseDTO = null;
try {
responseDTO = ResponseDTO.builder()
.status(HttpStatus.OK.toString())
.body(future.get()).build(); // current thread waits for result
System.out.println("Thread freed : " +Thread.currentThread().getName()); // This line prints as soon as service tasks completes
ResponseEntity responseEntity = ResponseEntity.ok(responseDTO);
deferredResult.setResult(responseEntity);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
} catch (ExecutionException e) {
System.out.println(e.getMessage());
}
return deferredResult;
@Async("threadPool")
public Future<String> getResult() throws InterruptedException {
System.out.println("Separate thread : "+Thread.currentThread().getName());
Thread.sleep(6000);
System.out.println("Separate thread Async task completed : "+Thread.currentThread().getName());
return new AsyncResult<>("Success");
}
@GetMapping(“/temp/{id}”)
public DeferredResult>DeferredResult=新的DeferredResult();
Future=productService.getResult()//异步调用服务方法
System.out.println(“当前线程执行:+Thread.currentThread().getName());//并行执行并立即打印此行
ResponseDTO ResponseDTO=null;
试一试{
responseDTO=responseDTO.builder()
.status(HttpStatus.OK.toString())
.body(future.get()).build();//当前线程等待结果
System.out.println(“线程释放:+Thread.currentThread().getName());//此行在服务任务完成后立即打印
ResponseEntity ResponseEntity=ResponseEntity.ok(responseDTO);
延迟结果。设置结果(响应性);
}捕捉(中断异常e){
System.out.println(e.getMessage());
}捕获(执行例外){
System.out.println(e.getMessage());
}
返回延迟结果;
服务:
@GetMapping("/temp/{id}")
public DeferredResult<ResponseEntity<?>> findByIdTemp(@PathVariable Long id) {
System.out.println("Request received : "+Thread.currentThread().getName());
final DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>();
Future<String> future = productService.getResult(); //Async call to service method
System.out.println("Current Thread Execution: " +Thread.currentThread().getName()); // Execute parallely and print this line immediately
ResponseDTO responseDTO = null;
try {
responseDTO = ResponseDTO.builder()
.status(HttpStatus.OK.toString())
.body(future.get()).build(); // current thread waits for result
System.out.println("Thread freed : " +Thread.currentThread().getName()); // This line prints as soon as service tasks completes
ResponseEntity responseEntity = ResponseEntity.ok(responseDTO);
deferredResult.setResult(responseEntity);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
} catch (ExecutionException e) {
System.out.println(e.getMessage());
}
return deferredResult;
@Async("threadPool")
public Future<String> getResult() throws InterruptedException {
System.out.println("Separate thread : "+Thread.currentThread().getName());
Thread.sleep(6000);
System.out.println("Separate thread Async task completed : "+Thread.currentThread().getName());
return new AsyncResult<>("Success");
}
@Async(“线程池”)
public Future getResult()引发InterruptedException{
System.out.println(“分离线程:+thread.currentThread().getName());
睡眠(6000);
System.out.println(“单独线程异步任务已完成:“+thread.currentThread().getName()”);
返回新的异步结果(“成功”);
}
控制器方法似乎正在等待服务方法的响应
是,控制器方法正在等待来自productService
的响应,因为dnCallBackPool
中的@Async
线程只负责执行productService
中的getResult()
方法
但是try-catch
块中的代码由web容器线程执行(例如http-nio-8080-exec-1
)
因此productService.getResult()
上的Future
对象调用是一个阻塞调用,如果当前线程应该等到@Async
线程完成其进程并返回结果
如有必要,等待计算完成,然后检索其结果
因此,在控制器方法末尾的Future
对象上执行get()
,以便两个方法并行执行,下面是一个示例
控制器:
@GetMapping("/temp/{id}")
public DeferredResult<ResponseEntity<?>> findByIdTemp(@PathVariable Long id) {
System.out.println("Request received : "+Thread.currentThread().getName());
final DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>();
Future<String> future = productService.getResult(); //Async call to service method
System.out.println("Current Thread Execution: " +Thread.currentThread().getName()); // Execute parallely and print this line immediately
ResponseDTO responseDTO = null;
try {
responseDTO = ResponseDTO.builder()
.status(HttpStatus.OK.toString())
.body(future.get()).build(); // current thread waits for result
System.out.println("Thread freed : " +Thread.currentThread().getName()); // This line prints as soon as service tasks completes
ResponseEntity responseEntity = ResponseEntity.ok(responseDTO);
deferredResult.setResult(responseEntity);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
} catch (ExecutionException e) {
System.out.println(e.getMessage());
}
return deferredResult;
@Async("threadPool")
public Future<String> getResult() throws InterruptedException {
System.out.println("Separate thread : "+Thread.currentThread().getName());
Thread.sleep(6000);
System.out.println("Separate thread Async task completed : "+Thread.currentThread().getName());
return new AsyncResult<>("Success");
}
@GetMapping(“/temp/{id}”)
public DeferredResult>DeferredResult=新的DeferredResult();
Future=productService.getResult()//异步调用服务方法
System.out.println(“当前线程执行:+Thread.currentThread().getName());//并行执行并立即打印此行
ResponseDTO ResponseDTO=null;
试一试{
responseDTO=responseDTO.builder()
.status(HttpStatus.OK.toString())
.body(future.get()).build();//当前线程等待结果
System.out.println(“线程释放:+Thread.currentThread().getName());//此行在服务任务完成后立即打印
ResponseEntity ResponseEntity=ResponseEntity.ok(responseDTO);
延迟结果。设置结果(响应性);
}捕捉(中断异常e){
System.out.println(e.getMessage());
}捕获(执行例外){
System.out.println(e.getMessage());
}
返回延迟结果;
服务:
@GetMapping("/temp/{id}")
public DeferredResult<ResponseEntity<?>> findByIdTemp(@PathVariable Long id) {
System.out.println("Request received : "+Thread.currentThread().getName());
final DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>();
Future<String> future = productService.getResult(); //Async call to service method
System.out.println("Current Thread Execution: " +Thread.currentThread().getName()); // Execute parallely and print this line immediately
ResponseDTO responseDTO = null;
try {
responseDTO = ResponseDTO.builder()
.status(HttpStatus.OK.toString())
.body(future.get()).build(); // current thread waits for result
System.out.println("Thread freed : " +Thread.currentThread().getName()); // This line prints as soon as service tasks completes
ResponseEntity responseEntity = ResponseEntity.ok(responseDTO);
deferredResult.setResult(responseEntity);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
} catch (ExecutionException e) {
System.out.println(e.getMessage());
}
return deferredResult;
@Async("threadPool")
public Future<String> getResult() throws InterruptedException {
System.out.println("Separate thread : "+Thread.currentThread().getName());
Thread.sleep(6000);
System.out.println("Separate thread Async task completed : "+Thread.currentThread().getName());
return new AsyncResult<>("Success");
}
@Async(“线程池”)
public Future getResult()引发InterruptedException{
System.out.println(“分离线程:+thread.currentThread().getName());
睡眠(6000);
System.out.println(“单独线程异步任务已完成:“+thread.currentThread().getName()”);
返回新的异步结果(“成功”);
}
Tanks等待回复。但是,直到服务方法发出响应,控制器方法才释放。下面是我得到的答复<收到的代码>请求:http-nio-8080-exec-1当前线程执行:http-nio-8080-exec-1独立线程:dnCallBackPool-1独立线程异步任务已完成:dnCallBackPool-1线程已释放:http-nio-8080-exec-1但线程已释放的行不应等待来自服务方法的响应。等待响应。但是,直到服务方法发出响应,控制器方法才释放。下面是我得到的答复<代码>收到的请求:http-nio-8080-exec-1当前线程执行:http-nio-8080-exec-1独立线程