Async简介:
异步方法调用使用场景:处理日志、发送邮件、短信......
spring中提供了@Async来实现异步方法。
@Async修饰类,则该类所有方法都是异步的,@Async修饰方法,则该方法是异步的。
被修饰的方法在被调用时,会在一个新的线程中执行。
Spring中通过在方法上设置@Async
注解,可使得方法被异步调用。也就是该方法会在调用时立即返回,而这个方法的实际执行交
给Spring的TaskExecutor去完成
1. 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
2. 如果此时线程池中的数量等于corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
3. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maxPoolSize,建新的线程来处理被添加的任务。
4. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maxPoolSize,那么通过handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
5. 当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
本次记录Async使用场景:需要调用其他服务,并且主线程需要继续完成当前线程任务
第一步:需要去做事的类
@Component
@EnableScheduling
public class VideoStatusUpdateServiceImpl implements VideoStatusUpdateService {
@Resource
private VaCaseVideoExtMapper vaCaseVideoExtMapper;
//每隔五秒
@Scheduled(cron = "*/5 * * * * ? ")
@Override
public void videoStatusUpdate() throws IOException {
//得到一个集合
List<VaCaseVideo> list = vaCaseVideoExtMapper.selectAllVideoes();
//遍历集合去创建异步线程,去做一些其他事情
for (VaCaseVideo vo : list) {
dealTask(vo);
}
}
@Async("asyncServiceExecutor")
public void dealTask(VaCaseVideo vo) throws IOException {
System.out.print("这里在做某件事情")
}
}
第二步:启动类上加上注解@EnableAsync,开启异步
@SpringBootApplication
@EnableAsync
@EnableCaching
public class StartApp {
public static void main(String[] args) {
SpringApplication.run(StartApp.class, args);
}
}
第三步:配置Executor(此步骤可有可无,若不配值则会使用默认值),配置自定义Executor
@Configuration
public class ExecutorConfig {
private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
@Bean
public Executor asyncServiceExecutor() {
logger.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(5);
//配置最大线程数
executor.setMaxPoolSize(60);
executor.setKeepAliveSeconds(180);
//配置队列大小
executor.setQueueCapacity(60);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix("async-service-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
第四步:启动项目,会每隔五秒打印需要做的事情