1.构造参数
int corePoolSize:核心的线程数,当调用execute的时候,如果当前线程数量小于corePoolSize的大小则创造新的线程
int maximumPoolSize:如果当前线程的数量已经大于或等于corePoolSize,而且workQueue已经满了,但是线程数量比maxmumPoolSize小则创建新的线程。如果比maxmumPoolSize大则调用RejectedExecutionHandler做处理。
long keepAliveTime:核心的线程的空闲保留时间
TimeUnit unit:keepAliveTime的单位
BlockingQueue<Runnable> workQueue:存储任务的队列
ThreadFactory threadFactory:线程创建的工厂
RejectedExecutionHandler handler:任务和线程满了之后的处理器
2.线程数量与业务关系
线程数量设置与业务有强联系,一般根据IO密集型和CPU密集型的任务,而设置不同的数量,当然和机器的CPU核数也相关。
1.IO密集型可以理解为需要连续的吞吐一个大数据。
2.CPU密集型可以理解为单一任务时间短,但是任务数量很多。
想要了解为什么要定义这两种类型,就需要先了解CPU的工作原理。早期的CPU只有一个核,如果某个线程的单次任务很长,长期占用着CPU,那么其他线程则无法获得CPU的使用,导致其他线程卡住。为了解决这个问题,就有了CPU时间片这个设定,CPU的使用被分割成了一小片一小片的使用时间,线程只能使用一小片时间,即使当前使用CPU的线程还没有跑完任务也需要先释放CPU的使用,然后所有线程再一起抢下一个时间片,这样可以防止CPU被某个线程长期占用,而导致其他线程卡住。
但是这种设计也会带来一些问题,例如线程切换的时候是一个耗时的操作,所以并不是线程多就代表好,需要根据不同的功能而设置线程数量。
IO密集型的任务,单个任务数据读写可能会比较大,为了能快速将数据读写完,可以对数据进行切割,然后多个线程同时进行数据的读写,所有IO密集型的任务可以适当的增加线程的数量。
CPU密集型的任务,单个任务的执行时间非常短,但是任务量很多,如果线程太多,会导致时间都消耗在线程的切换,所以CPU密集型的任务可以适当减少线程的数量。
参考
Java线程池实现原理及其在美团业务中的实践 - 美团技术团队 (meituan.com)
更好的使用JAVA线程池 - Float_Luuu的个人空间 - OSCHINA - 中文开源技术交流社区
什么是CPU密集型、IO密集型? - aspirant - 博客园 (cnblogs.com)