线程池参数设置原则
1 如何为线程池设置合适的线程参数?
目前根据一些开源框架,设置多少个线程数量通常是根据应用的类型**:I/O 密集型、CPU 密集型。**
- I/O密集型
- I/O密集型的场景在开发中比较常见,比如像 MySQL数据库读写、文件的读写、网络通信等任务,这类任务不会 特别消耗CPU资源,但是IO操作比较耗时,会占用比较多时间;
- IO密集型通常设置为 2n+1,其中 n 为 CPU 核数;
- 说白了,对于i/o密集型的场景,不太占用cpu资源,所以并发的任务数大于cpu的核数,这样的话能更加充分的利用CPU资源;
- CPU密集型
- CPU密集型的场景,比如像加解密,压缩、计算等一系列需要大量耗费 CPU 资源的任务,这些场景大部分都是纯 CPU计算;
- CPU密集型通常设置为n+1,这样也可避免多线程环境下CPU资源挣钱带来上下文频繁切换的开销;
2 如何获取当前服务器的cpu核数?
int cors= Runtime.getRuntime().availableProcessors();
3 无界队列问题
实际运行中,我们一般会设置线程池的阻塞队列长度,如果不设置,则采用默认值:
private int corePoolSize = 1;
private int maxPoolSize = Integer.MAX_VALUE;
private int keepAliveSeconds = 60;
private int queueCapacity = Integer.MAX_VALUE;
在这个过程中,如果设置或者使用不当,容易造成内存溢出问题,同时如果设置了无界队列,那么线程池的最大线程数也就失去了意义;
所以企业开发中会命令禁止使用默认的队列长度;