在Spring Boot中实现异步请求、并行执行,可以使用@Async
注解来定义异步方法,同时使用Future
、CompletableFuture
或其他异步处理机制来处理异步结果和回调。以下是实现这一功能的几个步骤:
开启异步支持
首先,需要在Spring Boot应用中开启异步支持。这可以通过在一个配置类上添加@EnableAsync
注解来实现。AsyncConfig 类开启异步支持并自定义Executor
java
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("Async-");
executor.initialize();
return executor;
}
}
定义异步服务
然后,定义一个服务类,并在其中的方法上使用@Async
注解来标记它们为异步方法。这里可以返回Future
、CompletableFuture
或ListenableFuture
等,以便处理异步结果。
java
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Service
public class AsyncService {
@Async
public CompletableFuture<String> processAsync() {
// 模拟异步任务
try {
Thread.sleep(1000);
return CompletableFuture.completedFuture("单个任务执行完成");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return CompletableFuture.failedFuture(e);
}
}
@Async
public CompletableFuture<String> processAsyncParallel(int taskNumber) {
// 模拟异步任务
try {
Thread.sleep(1000); // 假设这是耗时操作
return CompletableFuture.completedFuture("任务 #" + taskNumber + " 执行完成");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return CompletableFuture.failedFuture(e);
}
}
public List<CompletableFuture<String>> executeTasksInParallel() {
List<CompletableFuture<String>> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
futures.add(processAsyncParallel(i));
}
return futures;
}
}
在Controller中调用并行执行方法并等待所有任务完成
在AsyncController
中,我们将添加一个映射来启动并行任务并等待它们全部完成。
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@RestController
public class AsyncController {
@Autowired
private AsyncService asyncService;
@GetMapping("/startParallelTasks")
public String startParallelTasks() {
List<CompletableFuture<String>> futures = asyncService.executeTasksInParallel();
// 等待所有任务完成
CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
allDoneFuture.thenAccept(results -> results.forEach(System.out::println));
return "并行任务开始执行";
}
@GetMapping("/waitForSpecificTask")
public String waitForSpecificTask() throws Exception {
CompletableFuture<String> future = asyncService.processAsync();
// 等待特定任务完成
String result = future.get(); // 阻塞直到任务完成
return "特定任务完成,结果:" + result;
}
}
说明
executeTasksInParallel
方法在AsyncService
中启动了多个并行的异步任务。这些任务通过CompletableFuture
并行执行。- 在
startParallelTasks
中,我们使用CompletableFuture.allOf
来等待所有任务完成。allOf
返回一个新的CompletableFuture
,该CompletableFuture
在所有给定的CompletableFutures
完成时完成。 waitForSpecificTask
方法演示了如何等待一个特定的异步任务完成。使用CompletableFuture.get()
方法可以阻塞当前线程直到异步任务完成,并获取结果。
代码示例展示了如何在Spring Boot应用中并行执行多个异步任务,并等待特定或所有任务的完成,充分利用@Async
注解和CompletableFuture
的能力来实现高效的异步编程模式。