利用spring ThreadPoolExecutor实现多线程
处理高耗时任务时,使用多线程可以提高效率。
创建线程池
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean("taskExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程数5:线程池创建时候初始化的线程数
executor.setCorePoolSize(5);
//最大线程数5:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
executor.setMaxPoolSize(5);
//缓冲队列500:用来缓冲执行任务的队列
executor.setQueueCapacity(500);
//允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
executor.setKeepAliveSeconds(60);
//线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
executor.setThreadNamePrefix("ExecutorThread-");
executor.initialize();
return executor;
}
}
使用线程池
@Service
public class InfoService {
private InfoDao infoDao;
@Autowired
public InfoService(InfoDao infoDao){
this.infoDao = infoDao;
}
//标注为异步任务,用线程池执行
@Async("taskExecutor")
//异步方法返回类型要求为CompletableFuture
public CompletableFuture<Info> getInfoById(int id){
//假设这个方法执行5秒
try {
Thread.sleep(5000);
}catch (Exception e){
}
return CompletableFuture.completedFuture(infoDao.getInfoById(id));
}
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class AsyncTest {
private static final Logger logger = LoggerFactory.getLogger(AsyncTest.class);
@Autowired
private InfoService infoService;
@Test
public void asyncTest() throws InterruptedException, ExecutionException {
// Start the clock
long start = System.currentTimeMillis();
CompletableFuture<Info> info1 = infoService.getInfoById(1);
CompletableFuture<Info> info2 = infoService.getInfoById(1);
CompletableFuture<Info> info3 = infoService.getInfoById(1);
CompletableFuture<Info> info4 = infoService.getInfoById(1);
CompletableFuture<Info> info5 = infoService.getInfoById(1);
// Wait until they are all done
CompletableFuture.allOf(info1,info2,info3,info4,info5).join();
// Print results, including elapsed time
float exc = (float)(System.currentTimeMillis() - start)/1000;
logger.info("Elapsed time: " + exc + " seconds");
}
}
执行测试,多线程大大缩短了执行时间。