iso*_*yer 0 java spring asynchronous spring-boot spring-async
@Async这是Spring Boot 中正确的使用方法吗?
@Service
class someServiceImpl {
...
public someResponseDTO getUsers(int userId) {
// Do some logic
...
// Call external API with another service method from another service impl
anotherService.emailUserInTheBackground(userId);
return someResponseDTO;
}
...
}
Run Code Online (Sandbox Code Playgroud)
@Service
public class AnotherService {
@Async
public void emailUserInTheBackground(int userId) {
// This might take a while...
...
}
}
Run Code Online (Sandbox Code Playgroud)
既然emailUserInTheBackground()有@Async注释和返回类型,它会完全void阻塞该行吗?return someResponseDTO
我想要的只是将响应返回给调用者而无需等待,因为emailUserInTheBackground()完成时间太长并且不直接绑定到响应对象。
是的,这是在后台运行任务的正确方法,您可以通过引入延迟来模仿线程阻塞行为。
@SpringBootApplication
@EnableAsync
public class MyApplication {
public static void main(String[] arg) {
SpringApplication.run(MyApplication.class);
}
}
Run Code Online (Sandbox Code Playgroud)
那么你需要用@Async注释来标记emailUserInTheBackground方法。
@Service
class AnotherService {
@Async
public void emailUserInTheBackground(int userId) {
try {
TimeUnit.SECONDS.sleep(10);
System.out.println("Print from async: "+ Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在方法调用之后再添加一个记录器,getUsers(...)即使 emailService 线程被阻塞 10 秒,您也会看到调用首先在不同的线程中完成。
anotherService.emailUserInTheBackground(userId);
System.out.println("Print from service: "+ Thread.currentThread().getName());
Run Code Online (Sandbox Code Playgroud)
您还可以使用 CompletableFuture 在后台运行任务。
public someResponseDTO getUsers(int userId) {
// some other task
...
// Call external API with another service method from another service impl
CompletableFuture.runAsync(() -> anotherService.emailUserInTheBackground(userId))
return someResponseDTO;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6936 次 |
| 最近记录: |