1.application.properties配置线程池参数
#核心线程数,当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程,设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时退出
spring.task.pool.corePoolSize=20
#最大线程数,当线程数大于等于corePoolSize,且任务队列已满时,线程池会创建新线程来处理任务
spring.task.pool.maxPoolSize=60
#线程空闲时间,当线程空闲时间达到keepAliveSeconds(秒)时,线程会退出,直到线程数量等于corePoolSize,如果allowCoreThreadTimeout=true,则会直到线程数量等于0
spring.task.pool.keepAliveSeconds=1
#任务队列容量,当核心线程数达到最大时,新任务会放在队列中排队等待执行
spring.task.pool.queueCapacity=400
2.创建线程池配置类AsyncTaskConfig
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@EnableAsync
public class AsyncTaskConfig {
@Autowired
private TaskThreadPoolConfig config;
// ThredPoolTaskExcutor的处理流程
// 当池子大小小于corePoolSize,就新建线程,并处理请求
// 当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理
// 当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
// 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁
// 当threadNamePrefix设置为true,则核心线程也会超时关闭
@Bean
public ThreadPoolTaskExecutor myTaskAsyncPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(config.getCorePoolSize());
executor.setMaxPoolSize(config.getMaxPoolSize());
executor.setQueueCapacity(config.getQueueCapacity());
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
executor.setAllowCoreThreadTimeOut(true);
executor.setThreadNamePrefix("MyExecutor-");
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
3.创建taskService并添加方法
不带返回值:
@Async("myTaskAsyncPool")
public void transJkrz(Map<String, Object> m) {
System.out.println("我被异步调用了");
}
带返回值:
@Async("myTaskAsyncPool")
public Future<String> transTest(WmsGoods wmsGoods) {
String result = "";//返回结果(0:异常,1:成功,2:失败)
try {
List<Map<String,Object>> list = customerDao.queryGoodsByOE(wmsGoods);
if(list == null || list.size() == 0){
customerDao.insertGoods(wmsGoods);
result = "1";
}else{
result = "2";
}
} catch (Exception e) {
result = "0";
e.printStackTrace();
}
return new AsyncResult<String>(result);
}
4.在Controller中调用方法
不带返回值:
@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;
@RequestMapping(value = "list.htm", method = {RequestMethod.GET, RequestMethod.POST })
public void list(HttpServletRequest request) throws Exception{
List<Map> list = new ArrayList<Map>();//可根据业务查询库中数据
for(Map m : list){
taskService.transJkrz(m);
}
//判断线程是否全部执行结束
while (threadPoolTaskExecutor.getActiveCount() > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("执行结束");
}
带返回值:
@PostMapping(value="/importTest")
public void importTest() throws Exception{
System.out.println("开始执行");
long start11 = System.currentTimeMillis();
List<Future<String>> futureList = new ArrayList<>();
for(int i=0;i<500;i++){
Future<String> future = customerService.transTest();
futureList.add(future);
}
for (Future future : futureList) {
//future.get()方法会堵塞当前线程,直到返回结果
String futureResult = (String) future.get();
}
System.out.println("执行完成,总耗时:"+(System.currentTimeMillis()-start11));
}