当前位置: 首页 > news >正文

单线程和多线程

单线程和多线程,本质是在讲:一个程序里有几条执行路线。

可以先记住一句话:

单线程:一个人干活,一次只能做一件事。 多线程:多个人一起干活,可以同时推进多件事。

但这里的“同时”要分清楚:有时是真同时,有时只是切换得很快,看起来像同时。

一、先理解进程和线程

一个程序运行起来后,操作系统会给它分配资源,这个运行中的程序叫:

进程 Process

比如你打开 Chrome、微信、VS Code,它们都是进程。

线程是进程里的执行单位:

线程 Thread

可以这样理解:

进程 = 一个公司 线程 = 公司里的员工

一个进程至少有一个线程。这个默认线程通常叫主线程。

线程之间共享同一个进程里的资源,比如内存、文件句柄、网络连接等。但每个线程也有自己的调用栈、执行位置、局部变量等。

二、单线程是什么

单线程就是一个进程里主要只有一条执行路线。

任务 A -> 任务 B -> 任务 C -> 任务 D

一次只能执行一个任务。前一个任务没执行完,后一个任务不能真正开始执行。

如果doSomethingSlow()很耗时,那么console.log("B")要等它结束后才能执行。

单线程的特点:

执行顺序简单

不容易出现数据竞争

不需要复杂的锁

调试相对容易

但一个任务卡住,后面的任务都会受影响

典型例子:

浏览器里的 JavaScript 主线程

Redis 早期核心命令处理模型

简单脚本程序

很多 UI 程序的主线程

三、单线程的优点

单线程最大的优点是简单。

因为只有一条执行线,所以你不用担心两个线程同时修改同一个变量

单线程里结果很明确,最后就是2

它不会出现“两个线程同时读到旧值,然后互相覆盖”的问题。

所以单线程程序通常:

思路清晰

状态管理简单

不容易死锁

不需要频繁加锁

行为更可预测

四、单线程的缺点

单线程的问题也很明显:怕卡。

如果一个任务执行很久,整个线程都会被占住。

比如浏览器中:

while (true) { // 死循环 }

这个代码会让页面卡死。因为 JavaScript 主线程被死循环占住了,浏览器没机会处理点击、滚动、渲染等任务。

单线程常见问题:

一个慢任务会拖住所有后续任务

无法充分利用多核 CPU

CPU 密集型任务容易卡顿

阻塞式 I/O 会严重影响响应能力

五、多线程是什么

多线程就是一个进程里有多条执行路线。

线程 1:任务 A -> 任务 B 线程 2:任务 C -> 任务 D 线程 3:任务 E -> 任务 F

这些线程可以同时推进不同任务。

如果电脑有多个 CPU 核心,多个线程可以真正并行运行。

比如:

CPU 核心 1 执行线程 A CPU 核心 2 执行线程 B CPU 核心 3 执行线程 C

这就是真正的并行。

如果只有一个 CPU 核心,多线程也可以运行,但不是同时执行,而是操作系统快速切换:

线程 A 执行一会儿 切到线程 B 执行一会儿 再切到线程 C 执行一会儿 再切回线程 A

这种叫并发,不是真正并行。

六、多线程的优点

多线程适合把任务分开做。

比如一个图像处理程序:

线程 1:处理图片上半部分 线程 2:处理图片下半部分

如果有多个 CPU 核心,速度可能明显提升。

再比如一个桌面软件:

主线程:负责界面响应 后台线程:负责下载文件 后台线程:负责解析数据 后台线程:负责保存日志

这样界面不会因为下载文件而卡死。

多线程的优点:

可以利用多核 CPU

可以让耗时任务放到后台

可以提高程序响应速度

可以同时处理多个请求

适合 CPU 密集型任务和后台任务

七、多线程的缺点

多线程最大的问题是复杂。

因为多个线程共享同一块内存,所以它们可能同时修改同一个数据。

比如:

count = 0 线程 A:读取 count,得到 0 线程 B:读取 count,得到 0 线程 A:count + 1,写回 1 线程 B:count + 1,写回 1

你以为两个线程各加了一次,结果应该是2

但最后可能是:

count = 1

这就是数据竞争,也叫竞态条件。

多线程常见问题:

数据竞争

死锁

活锁

线程饥饿

调试困难

锁竞争导致性能下降

上下文切换带来额外开销

八、什么是锁

为了解决多个线程同时修改共享数据的问题,需要加锁。

比如:

线程 A 要改 count,先拿锁。 线程 A 改完后释放锁。 线程 B 才能拿锁,再修改 count。

锁可以保证同一时间只有一个线程进入关键区域。

但锁也有代价:

写起来麻烦

用错可能死锁

锁太多会降低性能

锁粒度不好会影响并发效果

九、死锁是什么

死锁就是多个线程互相等对方释放资源,结果谁都走不下去。

比如:

线程 A 拿到了锁 1,等待锁 2 线程 B 拿到了锁 2,等待锁 1

结果:

A 等 B B 等 A 两个都卡住

这就是死锁。

十、 并发和并行

单线程、多线程还要和并发、并行区分开。

并发:

多个任务都在推进,但不一定同一瞬间执行。

并行:

多个任务真的在同一瞬间执行。

单核 CPU 上的多线程:

并发,但不并行

多核 CPU 上的多线程:

可以并发,也可以并行

单线程异步:

可以并发,但通常不并行
http://www.cnnetsun.cn/news/3876559.html

相关文章:

  • 为什么谱归一化是GAN训练的黄金法则?PyTorch-Spectral-Normalization-GAN原理解析
  • MySQL数据库核心概念与优化实践指南
  • 财务还在手工录单?2026年企业银企直连ERP实施服务商到底该怎么选
  • OBS多平台直播完整指南:obs-multi-rtmp插件3步实现同步推流
  • 069、YOLOv11改进-关键点检测头多任务扩展即插即用涨点实验
  • PushPin协作功能全解析:如何邀请好友共享与编辑你的软木板
  • no-littering:终极指南,让你的~/.config/emacs目录保持整洁如新
  • KRAGEN开发指南:Backend API接口设计与Graph of Thoughts模块扩展
  • 阿里 Qwen3.8-Max 解析:2.4T 参数旗舰首次开源,API 接入与踩坑指南
  • 百元耳机别只看降噪,轻量化佩戴才是日常刚需
  • 深耕扬州建设工程信息网站:揭秘招投标全流程与数据背后的真实逻辑
  • Unity色彩空间实战:Gamma与sRGB配置指南
  • AI搜索优化平台横评与选型指南
  • 终极指南:如何在5分钟内快速上手Dalamud FF14插件框架
  • PyCharm快速上手指南:三层设计哲学与核心效率技巧
  • 编导老师智能体:内容创作提效助手
  • Coco 在病房:一个企业级 AI Agent,如何帮住院医师省下每天三小时的文书时间
  • 水下航行器能量收集器动力学和控制研究附Matlab代码
  • 体育数据API一站式接入|覆盖18+项目纳米数据实时毫秒级推送
  • Claude Code 安装、配置与国产大模型接入保姆级教程-适合新手小白(包含个人各种踩坑记录)
  • 提升前端开发效率:gulp-file-include高级技巧与最佳实践
  • 网站建设所需资料全面指南:做企业官网前必看的清单与避坑手册
  • 鱼哥好书分享第67期:WorkBuddy保姆级教程,“双龙虾”合并后从入门到精通
  • Nginx接口复制技术:原理、配置与生产实践
  • SuperRDP终极指南:三步解锁Windows远程桌面完整功能
  • 开发者视角:Pixel Saver核心功能的代码实现原理
  • 从交互设计看摇骰聚会鳄鱼牙齿的用户体验优化策略
  • 计算机毕业设计之基于Spring Boot的新闻发布系统的设计与实现
  • 2024破局之道:揭秘高转化率人才网站建设方案与实战落地指南
  • Flunt实战案例:构建健壮的Customer实体验证逻辑