SpringBoot如何优雅的实现异步调用
时间: 2024-05-03 17:13:29 浏览: 75
Spring Boot提供了多种方式来实现异步任务,以下是其中两种优雅的实现方式:
1. 基于注解@Async
```java
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Service
public class AsyncService {
@Async
public void asyncTask() {
//异步任务执行的逻辑
}
}
```
2. 使用CompletableFuture实现异步任务
```java
@Service
public class AsyncService {
public CompletableFuture<String> asyncTask() {
CompletableFuture<String> future = new CompletableFuture<>();
//异步任务执行的逻辑
return future;
}
}
```
相关问题
springboot 优雅停止接收请求 等待线程执行完
在 Spring Boot 中,可以通过优雅停止来停止接收新的请求,并等待当前正在执行的线程执行完毕。具体实现方式如下:
1. 首先,在应用启动时创建一个线程池,用于处理请求。可以使用 Java 中的 ExecutorService 或 Spring 中的 ThreadPoolTaskExecutor。
2. 在 Spring Boot 应用中添加一个 ShutdownHook,当应用被关闭时,会调用这个 ShutdownHook。
3. 在 ShutdownHook 中,首先停止接收新的请求,然后等待当前正在执行的线程执行完毕。可以通过设置一个标志位来实现停止接收请求,然后在等待线程执行完毕时,使用 ExecutorService 或 ThreadPoolTaskExecutor 的 awaitTermination() 方法来等待所有线程执行完毕。
示例代码如下:
```java
@Component
public class GracefulShutdown implements ApplicationListener<ContextClosedEvent> {
private ExecutorService executorService; // 线程池
private volatile int runningTasks = 0; // 正在执行的任务数
public GracefulShutdown(ExecutorService executorService) {
this.executorService = executorService;
}
@Override
public void onApplicationEvent(ContextClosedEvent event) {
// 停止接收新的请求
stopAcceptingRequests();
// 等待所有任务执行完毕
waitForRunningTasksToFinish();
}
private void stopAcceptingRequests() {
// 设置标志位,停止接收新的请求
}
private void waitForRunningTasksToFinish() {
// 等待所有任务执行完毕
executorService.shutdown();
try {
if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
// 如果线程池中还有任务在执行,强制关闭线程池
executorService.shutdownNow();
}
} catch (InterruptedException e) {
// 异常处理
}
}
@Async // 在另一个线程中执行任务
public void executeAsyncTask(Runnable task) {
executorService.submit(() -> {
try {
task.run();
} finally {
// 任务执行完毕后,正在执行的任务数减1
runningTasks--;
}
});
// 正在执行的任务数加1
runningTasks++;
}
}
```
在上面的代码中,我们使用了 Spring 的 @Async 注解,将任务提交到线程池中异步执行,同时也记录了正在执行的任务数。在应用关闭时,我们可以通过设置标志位来停止接收请求,然后等待所有任务执行完毕。当线程池中没有正在执行的任务时,应用会成功关闭。
阅读全文