1、在启动类上加标记 @EnableAsync
@Slf4j
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
@EnableAsync
public class MyApplication extends SpringBootServletInitializer {
2、定义一个配置文件,取自 https://github.com/zq2599 中的一个,但不记得具体是哪个了
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Description : 异步线程池的配置类
* @Author : zq2599
* @Date : 2018-01-19 9:55
*/
@Configuration
@EnableAsync
public class ExecutorConfig {
private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
@Bean
public Executor asyncServiceExecutor() {
logger.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(5);
//配置最大线程数
executor.setMaxPoolSize(5);
//配置队列大小
executor.setQueueCapacity(99999);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix("async-service-");
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
3、使用,方法名上加 @Async(“asyncServiceExecutor”)
/**
* 这个方法只在外部调用才会开线程,内部调用就是一普通方法
*
* @param stuId
*/
@Override
@Async("asyncServiceExecutor")
public void matchPhoto(FaceSet faceSet, String stuId) {
StudentPhoto stuPhoto = this.getOne(new LambdaQueryWrapper<StudentPhoto>().eq(StudentPhoto::getXsid, stuId));
List<String> scoreList = new LinkedList<>();
int nums = matchResultService.getSelNums(stuId) + 1;
....
}
注意的是,在同个类内调用这个方法时就是一个同步方法,不会开启线程
另外,单元测试中,这个类是数据库操作不可用,项目跑起来后,数据库操作才正常