异步并发的实例
"""
在当今的 Web 应用开发领域,异步处理以及多任务并行处理对于提升系统的响应性与吞吐量起着至关重要的作用。Spring Boot 为我们提供了多种多样的机制来实现异步任务处理。接下来,本文将详细介绍如何利用这些机制对您的应用程序性能进行优化。
1. 引言
在高负载的情形之下,如果所有的请求均采用同步处理的方式,那么极有可能导致系统响应变得缓慢,甚至出现超时的情况。为了有效避免这种状况的发生,我们可以借助异步处理技术来提高应用程序的效率。Spring Boot 提供了简洁而强大的工具来支持异步任务处理。
2. 环境准备
请确保您的开发环境已经安装了以下软件:
- Java 11 或者更高的版本。
- Maven 3.6 或者更高的版本。
- Spring Boot 2.x 或者更高的版本。
3. 创建 Spring Boot 项目
首先,我们需要创建一个全新的 Spring Boot 项目。可以通过 Spring Initializr 迅速生成基本的项目骨架。
3.1 添加依赖
在 pom.xml 文件中添加必需的依赖,例如 spring-boot-starter-web 和 spring-boot-starter-aop(用于支持 @Async 注解)。
1<dependencies>
2    <dependency>
3        <groupId>org.springframework.boot</groupId>
4        <artifactId>spring-boot-starter-web</artifactId>
5    </dependency>
6    <dependency>
7        <groupId>org.springframework.boot</groupId>
8        <artifactId>spring-boot-starter-aop</artifactId>
9    </dependency>
10</dependencies>
3.2 启用异步支持
在主类上添加 @EnableAsync 注解,以此来启用异步支持。
1import org.springframework.boot.SpringApplication;
2import org.springframework.boot.autoconfigure.SpringBootApplication;
3import org.springframework.scheduling.annotation.EnableAsync;
4@SpringBootApplication
5@EnableAsync
6public class AsyncApplication {
7    public static void main(String[] args) {
8        SpringApplication.run(AsyncApplication.class, args);
9    }
10}
4. 配置线程池
为了能够更好地掌控异步任务的执行情况,我们通常会自定义一个线程池。
1import org.springframework.context.annotation.Bean;
2import org.springframework.context.annotation.Configuration;
3import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
4@Configuration
5public class AsyncConfig {
    @Bean("asyncExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2); // 核心线程数
        executor.setMaxPoolSize(5); // 最大线程数
        executor.setQueueCapacity(10); // 队列大小
        executor.setThreadNamePrefix("AsyncExecutor-"); // 线程名称前缀
        executor.initialize();
        return executor;
    }
}
5. 创建异步服务
接下来,我们将要创建一些异步服务方法,并使用 @Async 注解对它们进行标记。
1import org.springframework.scheduling.annotation.Async;
2import org.springframework.stereotype.Service;
3import java.util.concurrent.CompletableFuture;
4@Service
5public class AsyncService {
    @Async("asyncExecutor")
    public CompletableFuture<Void> performTaskOne() {
        System.out.println("Executing task one in " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return CompletableFuture.completedFuture(null);
    }
    @Async("asyncExecutor")
    public CompletableFuture<Void> performTaskTwo() {
        System.out.println("Executing task two in " + Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return CompletableFuture.completedFuture(null);
    }
    @Async("asyncExecutor")
    public CompletableFuture<Void> performTaskThree() {
        System.out.println("Executing task three in " + Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return CompletableFuture.completedFuture(null);
    }
}
6. 控制器
在控制器中,我们将调用这些异步服务方法,并等待它们完成。
1import org.springframework.beans.factory.annotation.Autowired;
2import org.springframework.web.bind.annotation.GetMapping;
3import org.springframework.web.bind.annotation.RestController;
4import org.springframework.web.context.request.async.DeferredResult;
5@RestController
6public class AsyncController {
    private final AsyncService asyncService;
    @Autowired
    public AsyncController(AsyncService asyncService) {
        this.asyncService = asyncService;
    }
    @GetMapping("/execute-tasks")
    public DeferredResult<Void> executeTasks() {
        DeferredResult<Void> deferredResult = new DeferredResult<>();
        CompletableFuture<Void> taskOneFuture = asyncService.performTaskOne();
        CompletableFuture<Void> taskTwoFuture = asyncService.performTaskTwo();
        CompletableFuture<Void> taskThreeFuture = asyncService.performTaskThree();
        CompletableFuture.allOf(taskOneFuture, taskTwoFuture, taskThreeFuture)
               .thenRun(() -> deferredResult.setResult(null));
        return deferredResult;
    }
}
7. 测试
启动应用并访问 /execute-tasks 路径,检查控制台输出,确认任务是否并行执行。
1Executing task one in AsyncExecutor-1
2Executing task two in AsyncExecutor-2
3Executing task three in AsyncExecutor-3
"""
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号