spring多线程实现+合理设置最大线程数和核心线程数

线程运行规则

画板

手动设置线程池,就要合理设置最大线程数和核心线程数,按照网上大多数的说法,都是跟服务器的CPU有关

1. 先看下机器的CPU核数,然后在设定具体参数:
1
System.out.println(Runtime.getRuntime().availableProcessors());

即 CPU核数 = Runtime.getRuntime().availableProcessors()

  1. 分析下线程池处理的程序是CPU密集型,还是IO密集型
    1. IO密集型:大量网络,文件操作
    2. IO密集型:核心线程数 = CPU核数 * 2
    3. CPU 密集型:大量计算,cpu 占用越接近 100%, 耗费多个核或多台机器
    4. CPU密集型:核心线程数 = CPU核数 + 1
    5. 注:IO密集型(某大厂实践经验)
    6. 核心线程数 = CPU核数 / (1-阻塞系数) 例如阻塞系数 0.8,CPU核数为4,则核心线程数为20

画板

maxPoolSize

当系统负载达到最大值时,核心线程数已无法按时处理完所有任务,这时就需要增加线程。每秒200个任务需要20个线程,那么当每秒达到1000个任务时,则需要(1000-queueCapacity)*(20/200),即60个线程,可将maxPoolSize设置为60。还有说法就是 cpuNUM*2 或者是cpuNUM*4

keepAliveTime

线程数量只增加不减少也不行。当负载降低时,可减少线程数量,如果一个线程空闲时间达到keepAliveTiime,该线程就退出。默认情况下线程池最少会保持corePoolSize个线程。

allowCoreThreadTimeout

默认情况下核心线程不会退出,可通过将该参数设置为true,让核心线程也退出。

queueCapacity

任务队列的长度要根据核心线程数,以及系统对任务响应时间的要求有关。队列长度可以设置为(corePoolSize/tasktime)*responsetime: (20/0.1)*2=400,即队列长度可设置为400。

队列长度设置过大,会导致任务响应时间过长,切忌以下写法:

LinkedBlockingQueue queue = new LinkedBlockingQueue();

这实际上是将队列长度设置为Integer.MAX_VALUE,将会导致线程数量永远为corePoolSize,再也不会增加,当任务数量陡增时,任务响应时间也将随之陡增。


spring多线程实现+合理设置最大线程数和核心线程数
https://luoyuanxiang.top/posts/35092.html
作者
罗远祥
发布于
2024年9月25日
许可协议