这是一个非常深刻且直击本质的问题!要解开这个疑惑,我们需要先区分两个概念:“CPU 利用率(CPU Utilization)”和“系统吞吐量(Throughput)”。
简单来说:程序使用多线程,主要目的并不是为了提高 CPU 利用率,而是为了提高系统的整体吞吐量(即单位时间内完成的任务数)。
我们可以从以下几个层面来剖析为什么“不采用多线程,CPU 利用率就不高”:
1. 核心原因:线程的“等待(阻塞)”状态在绝大多数实际应用中(如 Web 服务器、数据库、网络请求),程序大部分时间并不是在疯狂进行数学计算,而是在等待:
等待网络数据包到达(网络 I/O)等待数据从硬盘读取(磁盘 I/O)等待数据库返回结果等待锁的释放当单线程遇到这些“等待”时,它会进入阻塞状态。 此时,CPU 处于空闲状态,什么都不做,CPU 利用率就会断崖式下跌,甚至降到 0%。
多线程的作用: 当线程 A 在等待网络 I/O 时,操作系统会把 CPU 调度给线程 B 去执行其他任务。这样,CPU 始终有事可做,CPU 利用率自然就提高了。
2. 为什么 Redis 不需要多线程来提高 CPU 利用率?结合你引用的内容,Redis 之所以能“任性”地采用单线程,是因为它完美避开了上述的“等待”陷阱:
纯内存操作: Redis 的数据都在内存中,没有磁盘 I/O 的等待。非阻塞 I/O 多路复用: 它使用 epoll 等机制,在等待网络 I/O 时,主线程不会真的阻塞挂起,而是去处理其他准备好的连接。命令执行极快: 单次命令执行通常是微秒级的。结论: 因为 Redis 的主线程几乎永远不阻塞,它一直在高速运转,所以它的单核 CPU 利用率其实是非常高的(经常能跑到 100%)。既然单核已经满载且没有 I/O 等待,自然就不需要多线程来“填补 CPU 的空闲时间”了。
3. 多线程的真正目的:榨干多核性能与提高并发既然单线程也能把单核 CPU 跑满,为什么现代程序还要用多线程?
利用多核 CPU: 单线程再强,也只能用满 1 个 CPU 核心。如果你的服务器有 32 个核心,单线程程序最多只用 3.125% 的 CPU 算力。多线程可以将任务拆分到多个核心上并行计算,极大提高整体 CPU 利用率。应对真正的 CPU 密集型任务: 比如视频编解码、复杂加密算法、AI 模型推理。这些任务没有 I/O 等待,全是纯计算。单线程算需要 10 秒,32 个线程并行算可能只需要 0.5 秒。总结对比I/O 密集型
(如传统 Web 服务)
线程频繁阻塞等待,CPU 大量时间空闲,
CPU 利用率极低
线程 A 等待时,线程 B 顶上,CPU 持续工作,
CPU 利用率高
提高吞吐量,掩盖 I/O 延迟
内存极速操作
(如 Redis 核心逻辑)
几乎不阻塞,单核
CPU 利用率极高
引入多线程反而增加锁竞争和上下文切换,得不偿失
保持低延迟,简化并发控制
CPU 密集型
(如复杂计算)
跑满单核,
单核 CPU 利用率 100%
多核并行,
整体 CPU 利用率接近 100%
缩短计算时间,利用多核算力
所以,回到你的问题:不采用多线程时,CPU 利用率不高,并不是因为 CPU 算得慢,而是因为单线程在“发呆(等待 I/O)”。多线程就像是给 CPU 找了多个“打工人”,确保 CPU 这个“老板”永远有活可派。而 Redis 的主线程是个“超级卷王”,从不发呆,所以一个“打工人”就够了。