前面的章节中,我们介绍了使用@Async
注解来实现异步调用,但是,对于这些异步执行的控制是我们保障自身应用健康的基本技能。本文我们就来学习一下,如果通过自定义线程池的方式来控制异步调用的并发。
定义线程池
在springboot主类中定义一个线程池
@EnableAsync @Configuration class TaskPoolConfig{ @Bean("taskExecutor") public Executor taskExecutor(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心线程数10:线程池创建时候初始化的线程数 executor.setCorePoolSize(10); //最大线程数20:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程 executor.setMaxPoolSize(20); //缓冲队列200:用来缓冲执行任务的队列 executor.setQueueCapacity(200); //允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁 executor.setKeepAliveSeconds(60); //线程池对拒绝任务的处理策略:这里采用了CallerRunsPolicy策略, // 当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务; // 如果执行程序已关闭,则会丢弃该任务 executor.setThreadNamePrefix("taskExecutor-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } }
使用线程池
在定义了线程池之后,我们如何让异步调用的执行任务使用这个线程池中的资源来运行呢?方法非常简单,我们只需要在@Async
注解中指定线程池名即可,比如:
@Component public class Task { @Async("taskExecutor") public void doTaskOne(){ System.out.println("开始任务"); long start = System.currentTimeMillis(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("结束任务"); } }