一次性发多封邮件是一个比较耗时的功能,因此可以考虑借助于线程池
Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor.在开发中实现异步任务,我们可以在配置类中添加@EnableAsync开始对异步任务的支持,并在相应的方法中使用@Async注解来声明一个异步任务。
1.在application中配置线程
async:
executor:
thread:
core_pool_size: 5
max_pool_size: 5
queue_capacity: 99999
name:
prefix: async-service-
2.配置
@Configuration
@EnableAsync
public class ExecutorConfig {
private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
@Value("${async.executor.thread.core_pool_size}")
private int corePoolSize;
@Value("${async.executor.thread.max_pool_size}")
private int maxPoolSize;
@Value("${async.executor.thread.queue_capacity}")
private int queueCapacity;
@Value("${async.executor.thread.name.prefix}")
private String namePrefix;
@Bean(name = "asyncServiceExecutor")
public Executor asyncServiceExecutor() {
logger.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(corePoolSize);
//配置最大线程数
executor.setMaxPoolSize(maxPoolSize);
//配置队列大小
executor.setQueueCapacity(queueCapacity);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(namePrefix);
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
添加配置的时候也可以直接implements AsyncConfigurer,然后Override getAsyncExecutor()方法
@Override
public Executor getAsyncExecutor() {
logger.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(corePoolSize);
//配置最大线程数
executor.setMaxPoolSize(maxPoolSize);
//配置队列大小
executor.setQueueCapacity(queueCapacity);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(namePrefix);
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
--
public interface AsyncService {
/**
* 执行异步任务
* 可以根据需求,自己加参数拟定,我这里就做个测试演示
*/
void executeAsync();
}
--
@Service
public class AsyncServiceImpl implements AsyncService {
@Autowired
private SpringMailUtil springMailUtil;
private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);
@Override
@Async("asyncServiceExecutor")
public void executeAsync() {
logger.info("start executeAsync");
System.out.println("异步线程要做的事情");
try {
String[] receivers = {"m18915228146@163.com"};
String[] ccs = {"1617950759@qq.com"};
String title = "test";
String content = "hello";
springMailUtil.sendMailByText(receivers,ccs,title,content);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("可以在这里执行批量插入等耗时的事情");
logger.info("end executeAsync");
}
}
--
@RestController
public class AsyncTestController {
private static Logger logger = LoggerFactory.getLogger(AsyncTestController.class);
@Autowired
private AsyncService asyncService;
@GetMapping("/asynctest")
public String async(){
logger.info("主线程开始");
for (int i = 0; i < 5; i++) {
asyncService.executeAsync();
}
logger.info("主线程结束");
return "success";
}
}
--运行结果
--