Spring Boot对线程池做了简化处理,比使用JDK原生的并发API更简单、只需配置一个java.util.concurrent.TaskExecutor或其子类的Bean的配置类、并使用@EnableAsync声明;调用方使用@Async标注,即可生效。
一、定义配置类
配置类一般使用Spring提供的ThreadPoolTaskExecutor类,使用@Configuration注释为配置类、@EnableAsync注释为允许异步。
多个@Bean时,可以使用@Bean(name = “beanName”)给线程池取上名字;使用线程池时,使用@Async(“beanName”)指定线程池
多个@Bean时,如果没指定线程池名;使用时使用线程池定义的方法名,@Async(“functionName”)指定线程池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package net.zuze.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration @EnableAsync public class ThreadConfig { @Bean public ThreadPoolTaskExecutor executor(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10); executor.setMaxPoolSize(30); executor.setQueueCapacity(20); executor.setThreadNamePrefix("Executor-"); executor.setKeepAliveSeconds(1); executor.setThreadPriority(1); executor.setWaitForTasksToCompleteOnShutdown(true); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize();
return executor; } }
|
二、线程池的使用
使用@Async()注解、标注在方法上、即表示对线程池的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package net.zuze.service;
import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service;
@Service public class UserService {
@Async("executor") public void executeAsync() { System.out.println("异步线程要做的事情" + Thread.currentThread()); } }
|
三、测试
创建测试类进行测试、使用@RestController定义接口、需要引入spring-boot-starter-web.jar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package net.zuze.controller;
import net.zuze.service.UserService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController @RequestMapping("/") public class IndexController { @Resource private UserService userService;
@GetMapping("/async") public void async(){ for(int i=0;i<10;i++) { userService.executeAsync(); } } }
|
四、效果
其中Executor-为ThreadConfig.jar 中定义的线程名前缀 executor.setThreadNamePrefix(“Executor-“);
1 2 3 4 5 6 7 8 9 10
| 调用异步线程Thread[Executor-1,1,main] 调用异步线程Thread[Executor-6,1,main] 调用异步线程Thread[Executor-5,1,main] 调用异步线程Thread[Executor-7,1,main] 调用异步线程Thread[Executor-4,1,main] 调用异步线程Thread[Executor-8,1,main] 调用异步线程Thread[Executor-2,1,main] 调用异步线程Thread[Executor-9,1,main] 调用异步线程Thread[Executor-3,1,main] 调用异步线程Thread[Executor-10,1,main]
|