代码示例
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CommonThreadPoolExecutor {
private static final int CORE_POOL_SIZE = ?;
private static final int MAX_POOL_SIZE = ?;
private static final int QUEUE_CAPACITY = ?;
private static final Long KEEP_ALIVE_TIME = ?;
public static ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(QUEUE_CAPACITY),
new ThreadPoolExecutor.CallerRunsPolicy());
}
任务性质
CPU密集型任务
CPU密集型也叫计算密集型,指的是消耗系统的硬盘、内存性能,CPU要读写I/O(硬盘/内存)在很短时间就可以完成,CPU运算要花费很长时间,CPU密集任务只有在真正的多核CPU上才可能得到加速(通过多线程),而在单核CPU上,无论开几个模拟的多线程该任务都不可能得到加速,因为CPU总的运算能力就那些。
线程数配置
CPU密集型任务应配置尽可能小的线程,减少线程切换耗费的资源:
- 线程数=CPU个数+1
IO密集型任务
涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,CPU大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有限度。常见的大部分任务都是IO密集型任务,比如:数据库数据交互、文件上传下载、网络数据传输等等。
线程数配置
IO操作不占用CPU,CPU大部分时间都在等待IO操作完成,为提高CPU利用率,应加大线程数量:
- 线程数=2*CPU个数+1
依赖其他系统资源
任务对其他系统资源有依赖,如获取数据库返回结果,这时候等待时间过长,则CPU空闲的时间越长,增加线程数量设置,才能更好的利用CPU。
估算CPU合理值公式
-
最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU可用核心数目
-
最佳线程数目= CPU可用核心数目/(1-阻塞系数)
- CPU密集型阻塞因子为0
- IO密集型阻塞因子接近1
-
CPU可用核心数目获取(8核16线程,输出为16)
int Ncpu=Runtime.getRuntime().availableProcessors();
链接: 如何合理设置线程池大小.