线程池ThreadPoolTaskExecutor参数使用测试
线程池的执行流程
所有线程池的执行流程都相同,如下图所示
线程池不同场景测试
根据线程池不同参数进行测试
测试service
@Service
@Slf4j
public class ThreadPoolService {
@Resource
TaskExecutePool taskExecutePool;
public static int num = 1;
public void invokeThread(int count,int time){
for (int i = 0; i < count; i++) {
taskExecutePool.getThreadPoolTaskExecutor().execute(()->{
log.info("线程开始*****"+"当前还有{}个线程,队列容量为{},核心线程数{}",taskExecutePool.getThreadPoolTaskExecutor().getActiveCount(),taskExecutePool.getThreadPoolTaskExecutor().getPoolSize()
+taskExecutePool.getThreadPoolTaskExecutor().getCorePoolSize());
try {
num++;
Thread.sleep((long) (time+Math.random()*1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("线程结束,"+"当前还有{}个线程,队列容量为{},num{}",taskExecutePool.getThreadPoolTaskExecutor().getActiveCount(),taskExecutePool.getThreadPoolTaskExecutor().getPoolSize(),num);
});
}
}
}
测试controller
@RequestMapping("/thread/{count}/{time}")
public String startThread(@PathVariable int count,@PathVariable int time){
long starttime = System.currentTimeMillis();
threadPoolService.invokeThread(count,time);
long endtime = System.currentTimeMillis();
long second = (endtime - starttime)/1000;
return "执行" + second + "秒";
}
测试场景
1.小于核心线程数
2.大于核心线程数,小于工作队列
3.大于工作队列,小于工作队列+核心线程数
4.大于工作队列,小于工作队列+最大线程数
5.大于工作队列+最大线程数
核心线程数 | 最大线程数 | 队列大小 | 拒绝策略 | 发起线程数量 | 单个线程睡眠时间 | 异步接口返回时间 | 所有线程执行时间总和 | 活跃线程数 | 线程池线程数 |
---|---|---|---|---|---|---|---|---|---|
5 | 30 | 100 | CallerRunsPolicy | 1 | 5 | 0 | 5 | 1->0 | 1 |
1 | 5 | 0 | 5 | 1->0 | 2 | ||||
1 | 5 | 0 | 5 | 1->0 | 3 | ||||
4 | 5 | 0 | 6 | 4->0 | 5 | ||||
10 | 5 | 0 | 11 | 5->0 | 5 | ||||
50 | 5 | 0 | 55 | 5->0 | 5 | ||||
103 | 5 | 0 | 103 | 5->0 | 5 | ||||
120 | 5 | 0 | 35 | 20->0 | 20->5 | ||||
150 | 5 | 5 | 28 | 30->0 | 30->5 | ||||
200 | 5 | 16 | 39 | 30->0 | 30->5 |
6.如果是抛出异常的拒绝策略
{"code":"400","message":"Executor [java.util.concurrent.ThreadPoolExecutor@76bd0946[Running, pool size = 30, active threads = 30, queued tasks = 100, completed tasks = 0]] did not accept task: com.example.demo.service.impl.ThreadPoolService$$Lambda$925/759725605@5c2f29bb","data":null}
总结
超过线程池容量,会变成同步线程阻塞,等线程池以最大线程数处理将线程容量处理到小于容量加最大线程数时才会变成同步线程。如果有一些共享变量,就会变得特别危险