并发与并行:核心概念辨析及技术演进
2026/6/3 10:29:24 网站建设 项目流程

1. 并发与并行的概念及区别
1.1 并发
1.1.1 早期无并发阶段
在计算机发展初期(约数十年前),硬件资源较为有限,CPU 通常仅具备单核心。此时,系统操作员需将待处理任务编排为顺序队列,依次交由 CPU 执行。

在该模式下,任务执行呈严格的串行化:前一个任务未执行完毕(未释放 CPU),后续任务无法开始执行(无法获取 CPU)。

1.1.2 单核并发机制
假设任务 3 需执行 4 秒,任务 4 需 6 秒,在完全串行执行时,总共需要 10 秒。
若任务 3 执行过程中需等待磁盘读取(耗时 2 秒),此时 CPU 处于空闲状态。引入并发机制后,任务 3 可在等待 I/O 时释放 CPU,任务 4 则在此期间获得 CPU 执行权。待任务 3 的磁盘读取完成,再重新申请 CPU 继续执行。

此时,两任务总执行时间缩短为 2 + 6 = 8 秒。其执行流程示意如下:

text

任务3:执行(2s) → 等待I/O(2s) → 执行(2s) 任务4:等待(2s) → 执行(6s)

在单核场景下,系统可通过任务切换在宏观上实现多任务“同时”执行的效果,尽管任一时刻仅有一个任务实际占用 CPU。这种基于时间片轮转的调度机制,显著提升了 CPU 利用率。

因此,可对并发进行如下归纳:

若系统支持多个任务交替执行、在宏观上同时存在,则称该系统支持并发。在单核 CPU 中,多个任务共享 CPU 时间片,通过快速切换营造“并行”假象。

1.1.3 多核并发扩展
随着硬件发展,多核 CPU 逐渐普及,每个核心可独立处理任务,并发机制依然适用,且能力进一步增强:

text

CPU1:任务1 → 任务3 → 任务5 CPU2:任务2 → 任务4 → 任务6

多核架构为并发执行提供了更充分的硬件支持。

1.2 并行
从多核并发的执行模型中可见,不同 CPU 核心可同时执行各自的任务队列。例如,CPU1 执行任务 3 的同时,CPU2 可执行任务 8。

因此,并行可定义为:

若系统支持在同一时刻有多个任务真正同时执行,则称该系统支持并行。并行可视为物理上的同时执行,如同多人并肩前行。

并发与并行的核心区别

  • 并发关注多个任务在一段时间内的交替执行与共存;

  • 并行强调多个任务在同一时刻的同时执行。


2. 同步与异步:执行模式对比
2.1 生活化示例:医院量血压
同步场景
小明到医院量血压,排队等候。每位体检者依次接受测量,前一人完成后,下一人才能开始。该过程严格按照时间顺序执行,称为同步执行

异步场景
小明排队时因心跳过快,医生建议其休息后再测。他暂离队伍,待状态恢复后重新排队完成测量。在该过程中,小明并未持续占据队列位置,而是在条件满足后重新加入流程,称为异步执行

2.2 代码示例说明
同步执行代码(TypeScript):

typescript

function testBPSync(name: string) { console.log(name, '测量血压'); } // 依次调用,顺序输出 testBPSync('体检者1'); testBPSync('体检者2'); testBPSync('小明'); testBPSync('体检者3');

异步执行代码(使用setTimeout):

typescript

function testBPAsync(name: string) { setTimeout(() => { console.log(name, '测量血压'); }, 2000); } testBPSync('体检者1'); testBPSync('体检者2'); testBPAsync('小明'); // 延迟执行,不阻塞后续代码 testBPSync('体检者3');

尽管小明在代码中位于体检者3之前调用,但其测量过程延迟执行,体现了异步特性。

2.3 异步是否等于多线程?
异步并不意味着一定在另一线程执行。例如setTimeout的回调仍在原线程(如浏览器的主线程)执行。
若要在真正独立的线程中执行,可借助多线程编程模型(以 Kotlin 为例):

kotlin

fun testBPAsync(name: String) { thread { println("$name 测量血压(在子线程执行)") } }

总结

  • 同步:代码在单一线程中按调用顺序依次执行。

  • 异步:代码的执行不必等待前序操作完成,可通过回调、事件等方式在当前或不同线程中延后执行。


3. 单线程与多线程:执行单元剖析
3.1 线程与进程的关系
操作系统以进程为资源分配的基本单位,以线程为 CPU 调度的基本单位。线程隶属于进程,共享进程资源,是任务执行的实际载体。

3.2 多线程的价值与挑战
多线程允许同一进程内的多个任务并发或并行执行,例如一个线程处理网络请求,另一个线程执行文件 I/O,从而提升整体效率。
然而,多线程也引入如下问题:

  • 互斥:多线程访问共享资源时需通过锁机制保证数据一致性。

  • 同步:线程间需通过信号、条件变量等机制协调执行顺序。
    因此,线程同步与互斥成为多线程编程的核心议题。
    单线程模型则天然避免此类问题,通常结合事件循环机制处理多任务。


4. 主线程与子线程:角色与职责
主线程通常是程序的入口线程,负责执行主函数(如main())。在 GUI 应用程序(如 Android、iOS)中,主线程常被指定为UI 线程,承担界面更新、事件响应等职责。为保证交互流畅,主线程应避免执行耗时操作(如网络请求、复杂计算),这些任务应交由子线程处理。

主线程与子线程在本质上是平等的调度单元,其区别主要源于框架或系统赋予的特定角色与约束。


5. JavaScript 执行引擎的单线程设计
JavaScript 在设计上采用单线程执行模型,主要原因包括:

  1. 避免多线程环境中的同步与锁机制带来的复杂性。

  2. 简化 UI 更新逻辑,确保 DOM 操作的安全性(仅限主线程更新界面)。

  3. 通过事件循环(Event Loop)与异步 I/O 机制,在单线程中实现非阻塞并发处理。

理解上述基础概念,有助于进一步深入学习 Promise、setTimeout 及事件循环等异步编程机制。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询