@EnableAsync、@Async注解使用
启动类:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; /** * 使用@Async注解需要在启动类加@EnableAsync注解 */ @SpringBootApplication @EnableAsync public class AsyncApplication { public static void main(String[] args) { SpringApplication.run(AsyncApplication.class, args); } }
@Async使用:
import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @Service public class TaskService { /** * @Async("taskExecutor")表示使用自定义线程池 */ @Async("taskExecutor") public void sendMessage1() { System.out.println(Thread.currentThread().getName() + "发送短信开始1 ..."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "发送短信结束1 ..."); } @Async("taskExecutor") public void sendMessage2() { System.out.println(Thread.currentThread().getName() + "发送短信开始2 ..."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "发送短信结束2 ..."); } private int batchInsert() { List<Integer> numList = new ArrayList<>(100000); for (int i = 0; i < 100000; i++) { numList.add(i); } return 1; } /** * @Async使用SpringBoot默认线程池 */ @Async public void batchAdd() { System.out.println(Thread.currentThread().getName() + "批量添加数据开始 ..."); batchInsert(); System.out.println(Thread.currentThread().getName() + "批量添加数据结束 ..."); } }
controller层:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import xinhaima.com.async.service.TaskService; @RestController public class TaskController { @Autowired private TaskService taskService; @RequestMapping(value = "/send", method = RequestMethod.GET) public void sendMsg() { taskService.batchAdd(); taskService.sendMessage1(); taskService.sendMessage2(); } }
线程池配置:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.ThreadPoolExecutor; /** * 线程池配置 */ @Configuration public class ThreadPoolTaskConfig { /** * 核心线程数(默认线程数) */ private static final int corePoolSize = 20; /** * 最大线程数 */ private static final int maxPoolSize = 100; /** * 允许线程空闲时间(单位:默认为秒) */ private static final int keepAliveTime = 10; /** * 缓冲队列大小 */ private static final int queueCapacity = 200; /** * 线程池名前缀 */ private static final String threadNamePrefix = "Async-Service-"; @Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名 public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.setKeepAliveSeconds(keepAliveTime); executor.setThreadNamePrefix(threadNamePrefix); // 线程池对拒绝任务的处理策略 // CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 初始化 executor.initialize(); return executor; } }
如下方式会使@Async失效:
- 异步方法使用static修饰
- 异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
- 异步方法不能与被调用的异步方法在同一个类中
- 类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
- 如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解
转载文章:https://www.toutiao.com/i6807650160445751820/