通过@Async注解来声明的任务是一个异步任务,那是不是,只要通过@Async注解声明后,就异步执行了呢?但是肯定不是的,需要通过@EnableAsync注解来声明配置类来开启对异步的支持。
配置类
@Configuration
@ComponentScan("ch3.taskexecutor")
@EnableAsync
public class Config {
}
服务类
@Service
public class AsyncTaskService {
@Async
public void executeAsyncTask(Integer i){
System.out.println("异步执行: " + i);
}
@Async
public void executeAsyncTaskPlus(Integer i){
System.out.println("异步执行+1: " + ++i);
}
}
执行类:
public class Main {
public static void main(String []args){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
AsyncTaskService service = context.getBean(AsyncTaskService.class);
for(int i = 0; i<10; i++){
service.executeAsyncTask(i);
service.executeAsyncTaskPlus(i);
}
context.close();
}
}
执行结构:
异步执行+1: 1
异步执行: 0
异步执行+1: 8
异步执行: 7
异步执行+1: 7
异步执行: 6
异步执行+1: 5
异步执行: 1
异步执行+1: 4
异步执行: 4
异步执行+1: 2
异步执行: 5
异步执行+1: 3
异步执行: 3
异步执行+1: 6
异步执行: 9
异步执行+1: 9
异步执行: 2
异步执行: 8
异步执行+1: 10
Process finished with exit code 0
执行完,进程也就退出了,有没有什么办法,不让主进程结束,让其一直等待任务执行呢,需要配置类继承AsyncConfigurer,并实现它的两个方法即可。
修改配置类:
@Configuration
@ComponentScan("ch3.taskexecutor")
@EnableAsync
public class Config implements AsyncConfigurer{
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
执行结果:
异步执行: 0
异步执行: 1
异步执行+1: 3
异步执行: 3
异步执行+1: 4
异步执行: 4
异步执行+1: 5
异步执行: 5
异步执行+1: 6
异步执行: 6
异步执行+1: 7
异步执行: 7
异步执行+1: 8
异步执行: 8
异步执行+1: 9
异步执行: 9
异步执行+1: 10
异步执行+1: 1
异步执行+1: 2
异步执行: 2
不过我们日常开发中,不会这样用,很多时候为了更好的控制线程执行,会使用线程池ThreadPoolTaskExecutor来执行任务。我们举个例子来看:
我们在配置类里定义一个ThreadPoolTaskExecutor的bean:
@Configuration
@ComponentScan("ch3.threadpooltask")
public class Config {
@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(10);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
}
定义一个实现Runnable的service:
@Service
@Scope("prototype")
public class AsyncTaskService implements Runnable{
private int i;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
@Override
public void run() {
System.out.println("我的i值是: " + i);
}
}
执行类:
public class Main {
public static void main(String []args){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
ThreadPoolTaskExecutor taskExecutor = context.getBean(ThreadPoolTaskExecutor.class);
for(int i = 0; i<10; i++){
AsyncTaskService service = context.getBean(AsyncTaskService.class);
service.setI(i);
taskExecutor.execute(service);
}
context.close();
}
}
执行结果:
我的i值是: 3
我的i值是: 4
我的i值是: 7
我的i值是: 5
我的i值是: 6
我的i值是: 1
我的i值是: 2
我的i值是: 0
我的i值是: 9
我的i值是: 8
看出来执行的结果是并行的。