目录
- 一、背景描述
- 二、简单使用方法
- 三、原理
- 五、使用自定义线程池
- 1、默认使用
- 2、如何使用自定义线程池
- 六、@Async失效情况
- 1、同一个类中,一个方法调用 @Async标注的方法
一、背景描述
java 的代码是同步顺序执行,当我们需要执行异步操作时我们通常会去创建一个新线程去执行。比如new Thread()。start(),或者使用线程池线程池 new ThreadPoolExecutor().execute 。
在 Springboot 中对其进行了简化处理,使用@EnableAsync + @Async 可以快速开启一个异步线程执行任务
二、简单使用方法
启动类上使用 @EnableAsync ,开启异步任务支持
@EnableAsync
@SpringBootApplication
public class TaskMain {public static void main(String[] args) {SpringApplication.run(TaskMain.class,args);}
}
在需要异步执行的方法上添加注解 @Async
@GetMapping("hello")public String hello(){asyncService.hello();System.out.println(new Date() + "success");return "ok";}@Asyncpublic void hello() {System.out.println(new Date() + " " + Thread.currentThread().getName() + Thread.currentThread().getId());try {Thread.sleep(6000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(new Date() + " " + Thread.currentThread().getName() + Thread.currentThread().getId() + "---->处理end");}
测试 Jemeter同时发送两个请求
三、原理
【看不太懂,之后再进行整理吧】
五、使用自定义线程池
1、默认使用
@Async默认使用的是 SimpleAsyncTaskExecutor , execute时,直接this.createThread(task) 也就是 new Tread来执行该任务
【缺点】SimpleAsyncTaskExecutor不限制并发线程且不重用线程,会为每个异步任务都创建有一个线程,在并发很高的情况下会导致程序内存耗尽
2、如何使用自定义线程池
1) 添加线程池配置,并将线程池注入到容器中
@Configuration
public class ThreadPoolConfig {@Bean("taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10);executor.setMaxPoolSize(20);executor.setQueueCapacity(200);executor.setKeepAliveSeconds(60);executor.setThreadNamePrefix("taskExecutor-");executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());return executor;}
}
2)使用@Async的时候,指定线程池
@Async("taskExecutor")public void hello() {System.out.println(new Date() + " " + Thread.currentThread().getName() + Thread.currentThread().getId());try {Thread.sleep(6000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(new Date() + " " + Thread.currentThread().getName() + Thread.currentThread().getId() + "---->处理end");}
六、@Async失效情况
1、同一个类中,一个方法调用 @Async标注的方法
@Service
public class AsyncDemoImpl implements AsyncDemo {// 注入spring上下文@Autowiredprivate ApplicationContext applicationContext;@Overridepublic void a() {System.out.println("开始执行a(): " + TimeUtil.getStringDate());// 通过上下文获取该类的实例,再调用该实例方法AsyncDemo asyncDemo = applicationContext.getBean(AsyncDemo.class);asyncDemo.b();System.out.println("执行结束a(): " + TimeUtil.getStringDate());}@Async@Overridepublic void b() {System.out.println("开始执行b(): " + TimeUtil.getStringDate());try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("执行结束b(): " + TimeUtil.getStringDate());}
}