提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
在我们的日常开发中,难免会遇到请求响应的速度慢的问题。这时就可以使用多线程的方式,一个方法多个线程同时执行,但是,不是所有的方法都能使用多线程,需具体问题具体分析。
多线程编程是指在一个程序中同时使用多个线程来执行任务。多线程编程的优势包括:
多线程编程也存在一些挑战,如线程同步、资源竞争和死锁等问题,需要合理设计和管理线程的执行。
实现多线程的方式有以下几种:
线程池构造器的7个参数:
在Spring Boot中配置多线程可以通过使用ThreadPoolTaskExecutor来实现。首先,需要在项目中添加一个异步配置类。这个配置类需要使用@Configuration和@EnableAsync注解,并实现AsyncConfigurer接口。在这个配置类中,你可以设置线程池的各种参数。比如,你可以设置CorePoolSize来指定线程池的最小线程数,MaxPoolSize来指定线程池的最大还可以设置ThreadNamePrefix来指定线程的名称前缀。在getAsyncExecutor方法中,你需要创建一个ThreadPoolTaskExecutor对象,并设置相应的参数。最后,通过调用initialize方法来初始化线程池,并将其返回。getAsyncUncaughtExceptionHandler方法用于设置线程池中出现异常时的处理方式。这里使用了SimpleAsyncUncaughtExceptionHandler作为默认的异常处理器。
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler; 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; import java.util.concurrent.ThreadPoolExecutor; /** * 线程池配置 */ @Configuration @EnableAsync public class ThreadPoolConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 核心线程数:线程池创建的时候初始化的线程数 executor.setCorePoolSize(10); // 最大线程数:线程池最大的线程数,只有缓冲队列满了之后才会申请超过核心线程数的线程 executor.setMaxPoolSize(20); // 等待队列:用来缓冲执行任务的队列 executor.setQueueCapacity(300); // 最大空闲时间:超过核心线程之外的线程到达200秒后会被销毁 executor.setKeepAliveSeconds(200); // 拒绝策略:超过线程容量,拒绝策略设置(由调用的线程执行) executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 线程名称前缀 executor.setThreadNamePrefix("Async Task-"); // 初始化线程 executor.initialize(); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new SimpleAsyncUncaughtExceptionHandler(); } }
通过以上的配置,你就可以在Spring Boot中使用多线程了。可以根据你的项目需求来设置合适的线程池参数。
通过controller层调用测试 Async。
@RestController @RequestMapping("/thread") public class ThreadPoolController { @Autowired private ThreadPoolService threadPoolService; @GetMapping("/test") public void threadTest () throws InterruptedException { for (int i = 0; i <= 10; i++) { threadPoolService.threadTest(i); } } }
通过@Async注解表明该方法是异步方法,如果注解在类上,那表明这个类里面的所有方法都是异步的。
@Service public class ThreadPoolServiceImpl implements ThreadPoolService { @Override @Async public void threadTest(int i) { System.out.println("线程" + Thread.currentThread().getName() + " 执行异步任务:" + i); } }
测试执行结果如下 线程的前缀“Async Task-”即为线程池配置中的线程名称前缀(可根据自己的喜好修改)
线程Async Task-3 执行异步任务:0 线程Async Task-2 执行异步任务:2 线程Async Task-1 执行异步任务:1 线程Async Task-2 执行异步任务:4 线程Async Task-3 执行异步任务:3 线程Async Task-5 执行异步任务:5 线程Async Task-1 执行异步任务:6 线程Async Task-2 执行异步任务:7 线程Async Task-4 执行异步任务:8 线程Async Task-6 执行异步任务:9