通过线程计数器实现带返回值的多线程调用
使用 @Async
注解结合线程计数器(CountDownLatch)时,可以通过使用 CompletableFuture
来支持异步方法的返回值。
首先,确保您已经配置了异步执行的线程池。在 Spring Boot 中,可以通过在主配置类上添加 @EnableAsync
注解来启用异步执行功能,并在配置文件中设置相关的线程池参数。
接下来,您可以按照以下步骤在方法中使用 @Async
注解和线程计数器:
- 创建一个
CountDownLatch
对象,并设置计数器的初始值。 - 在方法中使用
CompletableFuture
来包装异步执行的逻辑,并在逻辑完成后调用countDown()
方法来减少计数器的值。 - 在方法末尾调用
await()
方法等待计数器归零,以确保所有异步任务都已完成。
示例代码:
异步方法
@Component
public class MyTask {
@Async
public CompletableFuture<String> executeAsyncTask(CountDownLatch latch, int taskId) {
try {
// 执行异步任务的逻辑
System.out.println("Task " + taskId + " started.");
// 模拟耗时操作
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 任务完成时减少计数器
latch.countDown();
}
// 返回异步结果
return CompletableFuture.completedFuture("Task " + taskId + " completed.");
}
}
调用方法
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private MyTask myTask;
@RequestMapping(value = "/thread", method = RequestMethod.GET)
public void thread() throws InterruptedException {
// 定义异步任务数量
int taskCount = 5;
// 创建线程计数器
CountDownLatch latch = new CountDownLatch(taskCount);
// 启动异步任务
for (int i = 1; i <= taskCount; i++) {
CompletableFuture<String> future = myTask.executeAsyncTask(latch, i);
// 打印回调信息
future.thenAccept(result -> System.out.println("Async operation result: " + result));
}
// 等待所有任务完成
latch.await();
// 所有任务完成后的后续操作
System.out.println("All async operations completed");
}
}
打印结果
上述示例中,executeAsyncTask()
方法被标记为 @Async
注解,表示它将在异步线程中执行。计数器 latch
作为参数传递给这个方法,异步逻辑执行完成后会调用 countDown()
方法。模拟接口调用thread()
方法用于触发异步操作,并通过 thenAccept()
方法处理异步任务的完成结果。最后,await()
方法被调用来等待所有的异步任务完成。