@Async与异步任务——阅读开源项目中的代码
@Async注解:将一个方法指定为异步执行任务。需要配合线程池使用
示例:
1、建立Bean实体,使用@Async配置异步任务
1 import org.springframework.scheduling.annotation.Async; 2 import org.springframework.stereotype.Service; 3 4 /** 5 * Created by sang on 16-12-14. 6 */ 7 @Service 8 public class AsyncTaskService { 9 @Async 10 public void executeAsyncTask(int i) { 11 System.out.println("异步任务1:" + i+";Thread.currentThread().getName():"+Thread.currentThread().getName()); 12 } 13 14 @Async 15 public void executeAsyncTask2(int i) { 16 System.out.println("异步任务2:" + i+";Thread.currentThread().getName():"+Thread.currentThread().getName()); 17 } 18 }
2、配置异步执行环境:需要实现AsyncConfigurer接口
1 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 2 import org.springframework.context.annotation.ComponentScan; 3 import org.springframework.context.annotation.Configuration; 4 import org.springframework.scheduling.annotation.AsyncConfigurer; 5 import org.springframework.scheduling.annotation.EnableAsync; 6 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 7 8 import java.util.concurrent.Executor; 9 10 @Configuration 11 @ComponentScan("com.yrc.taskexecutor") 12 @EnableAsync //开启异步任务支持 13 public class TaskExecuteConfig implements AsyncConfigurer { 14 //获得基于线程池的任务执行器 15 @Override 16 public Executor getAsyncExecutor() { 17 //创建线程执行器 18 ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); 19 //执行核心线程数 20 taskExecutor.setCorePoolSize(2); 21 //指定线程最大数量 22 taskExecutor.setMaxPoolSize(5); 23 //指定任务队列最大长度 24 taskExecutor.setQueueCapacity(25); 25 //初始化执行器 26 taskExecutor.initialize(); 27 return taskExecutor; 28 } 29 30 @Override 31 public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 32 return null; 33 } 34 }
3、模拟调用:
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String args[]){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskExecuteConfig.class); AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class); for(int i=0;i<10;i++){ asyncTaskService.executeAsyncTask1(i); asyncTaskService.ExecuteAsyncTask2(i); } context.close(); } }
异步任务调用大致流程:当外部执行异步任务调用时,任务的实际执行会委派给线程池中的工作线程。先查询线程池中是否存在空闲线程,如果有,则立即将任务交给该工作线程,如果没有,则检测当前线程数量是否达到最大线程数量,没有则创建线程并交付任务,如果已经达到了最大线程数量,则检测当前任务队列是否满,如果没有满,则将任务放置入任务队列,如果 任务队列也满了,则执行相应的任务放弃策略。当主线程将工作交给任务线程后,就可以去执行其他任务,而工作线程在执行完任务后会将结果存入Future,然后根据当前状态和自己的身份选择继续存在还是销毁。当主线程想要获得最终结果时,调用Future.

浙公网安备 33010602011771号