除了应用默认线程池外,能够自定义应用的线程池(举荐)
定义线程池
第一步,先在 Spring Boot 主类中定义一个线程池,比方:
@EnableAsync
@Configuration
class TaskPoolConfig {@Bean("taskExecutor")
public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(200);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("taskExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
下面咱们通过应用 ThreadPoolTaskExecutor 创立了一个线程池,同时设置了以下这些参数:
- 外围线程数 10:线程池创立时候初始化的线程数
- 最大线程数 20:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过外围线程数的线程
- 缓冲队列 200:用来缓冲执行工作的队列
- 容许线程的闲暇工夫 60 秒:当超过了外围线程出之外的线程在闲暇工夫达到之后会被销毁
- 线程池名的前缀:设置好了之后能够不便咱们定位解决工作所在的线程池
- 线程池对回绝工作的解决策略:这里采纳了 CallerRunsPolicy 策略,当线程池没有解决能力的时候,该策略会间接在 execute 办法的调用线程中运行被回绝的工作;如果执行程序已敞开,则会抛弃该工作
- 在定义了线程池之后,咱们如何让异步调用的执行工作应用这个线程池中的资源来运行呢?办法非常简单,咱们只须要在 @Async 注解中指定线程池名即可,比方:
@Slf4j
@Component
public class Task {public static Random random = new Random();
@Async("taskExecutor")
public void doTaskOne() throws Exception {log.info("开始做工作一");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("实现工作一,耗时:" + (end - start) + "毫秒");
}
@Async("taskExecutor")
public void doTaskTwo() throws Exception {log.info("开始做工作二");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("实现工作二,耗时:" + (end - start) + "毫秒");
}
@Async("taskExecutor")
public void doTaskThree() throws Exception {log.info("开始做工作三");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("实现工作三,耗时:" + (end - start) + "毫秒");
}
}
单元测试
最初,咱们来写个单元测试来验证一下
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private Task task;
@Test
public void test() throws Exception {task.doTaskOne();
task.doTaskTwo();
task.doTaskThree();
//join 办法的作用是阻塞,即期待线程完结,才继续执行。Thread.currentThread().join();
}
}