CPU密集型(CPU-bound)和IO密集型(IO-bound)是两种常见的计算密集型和IO操作密集型任务类型
CPU密集型任务:
CPU密集型任务是指在执行过程中主要依赖于CPU处理能力的任务。
这类任务通常涉及大量的计算、逻辑判断、数据处理等操作。
例如,科学计算、图像处理、加密解密等任务都属于CPU密集型任务。
在CPU密集型任务中,CPU的处理能力是主要瓶颈,而IO操作相对较少。
IO密集型任务:
IO密集型任务是指在执行过程中主要依赖于IO操作(如磁盘读写、网络通信)的任务。
这类任务通常涉及大量的读取和写入操作,而CPU的计算需求相对较少。
例如,文件操作、数据库查询、网络爬虫等任务都属于IO密集型任务。
在IO密集型任务中,IO操作的速度和效率是主要瓶颈,而CPU的处理能力往往有闲置。
针对不同类型的任务,可以采取不同的优化策略:
对于CPU密集型任务,可以考虑优化算法、并行计算、利用多核CPU等方式来提高计算性能。
对于IO密集型任务,可以考虑使用异步IO、多线程或多进程并发处理、缓存技术等方式来提高IO操作的效率。
在实际应用中,任务的类型决定了对系统资源的需求和瓶颈,针对不同类型的任务进行合理的优化和资源分配,可以提高系统的性能和响应能力。
CPU密集表示,CPU操作较强,内存和硬盘配置较高,导致io处理极强,CPU占比100
线程数量 = CPU核数加1
初始化线程池:
public static ThreadPoolExecutor getCpuThreadExecutor(String threadName) {
// 获取CPU核数
int availableProcessors = Runtime.getRuntime().availableProcessors();
return new ThreadPoolExecutor(
availableProcessors + 1,
availableProcessors + 1,
30,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2048),
new CustomizableThreadFactory(threadName),
new ThreadPoolExecutor.CallerRunsPolicy());
}
IO强,表示CPU配置比硬盘,内存配置高很多,导致IO在操作很多数据时,CPU不会变很高
线程数量 = CPU核数乘以2 = CPU核数 /(1-0.8 或者 0.9)【0.8/0.9为阻塞系数】
初始化线程池:
public static ThreadPoolExecutor getIoThreadExecutor(String threadName) {
// 获取CPU核数
int availableProcessors = Runtime.getRuntime().availableProcessors();
return new ThreadPoolExecutor(
availableProcessors * 2,
availableProcessors * 2,
30,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2048),
new CustomizableThreadFactory(threadName),
new ThreadPoolExecutor.CallerRunsPolicy());
}
IO任务示例:
// 假设需要导出200W数据,不考虑数据顺序,开启多线程导出
@SneakyThrows
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = getIoThreadExecutor("io-Thread");
int count = count();
int num = 2000;
int size = count / num + ((count % num > 0) ? 1 : 0);
// 计数器
CountDownLatch countDownLatch = new CountDownLatch(size);
for (int i = 1; i <= size; i++) {
threadPoolExecutor.execute(() -> {
// page(i,num)
// write data...
// 任务执行完毕,计数器减一
countDownLatch.countDown();
});
}
// 阻塞主线程,等待所有线程执行完毕
countDownLatch.await();
// 关闭池子
threadPoolExecutor.shutdown();
}
补充知识:
ThreadPoolExecutor 是 Java 并发编程中重要的一个类,用于创建线程池。它有 7 个核心参数:
-
corePoolSize:核心线程数,线程池中始终存活的线程数。
-
maximumPoolSize:最大线程数,线程池中允许的最大线程数。
-
keepAliveTime:线程存活时间,线程池中超过核心线程数以外的线程空闲时间,超时就会被终止。
-
unit:时间单位,keepAliveTime 的单位。
-
workQueue:工作队列,用于保存等待执行的任务的阻塞队列。
-
threadFactory:线程工厂,用于创建线程。
-
handler:拒绝策略,当线程池无法处理更多任务时的策略。