深入理解CPU密集型与IO密集型任务、线程池如何选择?

目录

1、理解什么是CPU密集型与IO密集型

1.1 CPU密集型

概念解释

策略

1.2 I/O密集型

概念解释

策略

2、《Java并发编程实践》:具体的线程数该如何设置?线程池参数如何设置?

 参数解释

3、总结


1、理解什么是CPU密集型与IO密集型

1.1 CPU密集型

概念解释

        即,计算密集型,I/O能够在很短的时间内完成,而相对的CPU却有大量运算要处理。例如计算大量的加减乘除、矩阵运算等,都属于CPU密集型。

策略

        我们知道,线程是最小的可执行单位
        严格来说,每个核心同一时间只能处理一条线程的指令,因此如果是单核CPU的情况下,创建再多的线程其实也不会加快运算速度,反而会因为单核的线程并发导致线程上下文的切换而降低效率。(类似于一个工人干了多个活)
        而在多核cpu下,可以创建多个线程让多个cpu并行运算,一起工作。(多个工人同时做多个活),从而提升效率。

1.2 I/O密集型

        IO密集型指的是系统的CPU性能相对硬盘、内存要好很多,此时,大部分的状况是CPU在等I/O (硬盘/内存) 的读/写操作,但CPU的使用率不高。
        在实际开发中,IO密集型任务也很常见,例如:
        磁盘IO:读写本地的数据库、Redis,等。

        网络IO:http 请求、远程数据库读写、远程 Redis 读写,等

概念解释

        这里需要解释一下,什么叫“CPU在等I/O (硬盘/内存) 的读/写操作”?

        在传统的阻塞式 I/O 操作模型中,当 CPU 发起一个 I/O 请求后,发起该操作的线程会一直阻塞等待 I/O 操作的完成:
        当线程发起一个阻塞式的 IO 操作时,它会等待操作完成,期间线程将被挂起,无法继续执行其他指令,这种模型导致了CPU的使用率不高。需要注意的是,IO 阻塞并不是直接阻塞 CPU 的执行,而是阻塞了发起 IO 操作的线程。其他未受影响的线程仍然可以继续执行。

策略

        在上面的基础上我们知道,在处理IO密集型任务,即使创建了线程,也可能因为IO的阻塞等待而让线程阻塞、从而导致CPU不干活一直摸鱼🐟🐟
        为了不让cpu偷偷休息,可以增加更多的线程,当一个线程或进程在等待某个 I/O 操作完成时,其他线程或进程可以继续执行其他任务,减少了 CPU 空闲时间,这是可以通过线程池实现的复用技术。

2、《Java并发编程实践》:具体的线程数该如何设置?线程池参数如何设置?

结论:Ncpu 表示 核心数,线程数设置规则如下

如果是CPU密集型任务,就需要尽量压榨CPU,参考值可以设为 Ncpu+1

如果是IO密集型任务,参考值可以设置为 2 * Ncpu

 参数解释

        对于cpu密集型,之所以为Ncpu+1,因为:
        “
计算密集型的线程恰好在某时因为发生一个页错误或者因其他原因而暂停,刚好有一个“额外”的线程,可以确保在这种情况下CPU周期不会中断工作。”

        对于IO密集型,假设所有线程都被阻塞,有Ncp个空闲CPU,因此可以再多给一样数量的线程数,因此为2倍Ncpu

实际上,有这样的计算公式:

最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目

3、总结

        实际上,CPU密集型如果卡顿,往往是因为cpu不够用;IO密集型卡顿往往是因为线程不够用。 

 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好奇的7号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值