JS的多线程与线程池
线程与线程池原理全解析:打破单线程误区,从底层讲透转载请注明出处:本文从底层原理出发,把JS多线程和线程池讲得明白,看完再也不会被"JS单线程"的说法误导。一、先搞懂:JS到底是不是单线程?几乎所有入门教程第一句都会告诉你:JS是单线程语言。但这句话其实只说了一半,很多人学了好几年都没搞懂另一半。1.1 单线程到底指什么?我们说JS单线程,指的是JS的主线程是单线程:你写的JS业务代码,永远是在主线程上串行执行的DOM操作、页面渲染、事件循环调度,都在主线程上跑同一时间主线程只能干一件事,前一个任务没执行完,后面的任务只能等着这就是为什么你写个死循环,页面直接就卡了——主线程被占住了,渲染、交互都停了。1.2 另一半真相:JS运行时是多线程的但是!JS的运行环境(浏览器/Node.js)本身是多线程的,你每天都在用多线程,只是你自己不知道:你发个AJAX请求,网络请求是在专门的网络线程里跑的,不是主线程在等你读个本地文件,IO操作是在系统线程里跑的定时器计时、事件监听、图片解码,全都是在单独的线程里跑的举个最通俗的例子:你开了个奶茶店,你自己是收银员(主线程),负责点单收钱。你不可能点完单自己去做奶茶、煮珍珠、送外卖,那样后面的顾客全堵死了。所以你雇了几个后厨员工(其他线程)专门做这些事,你只负责点单,后厨做好了告诉你一声,你把奶茶给顾客就行。这就是JS的线程模型:主线程当收银员做核心调度,其他脏活累活丢给别的线程干,干好了通知主线程。单线程的是你这个收银员,整个奶茶店(运行时)是多线程的。1.3 为什么JS一开始要设计成主线程单线程?很多人觉得单线程是JS的缺陷,其实这是故意设计的,最核心的原因有两个:避免DOM操作冲突:如果JS是多线程,两个线程同时改DOM,一个要加节点一个要删节点,页面直接就乱了,还要加锁、同步,复杂度直接上天。单线程从根源上避免了这个问题。降低语言门槛:JS刚出来的时候就是给网页做简单交互的,要是一开始就搞多线程,光线程同步、死锁这些概念就能劝退90%的开发者,根本不可能有今天的生态。二、单线程的问题:为什么我们需要多线程?单线程好是好,但有个致命问题:阻塞。主线程就像收银员,要是遇到个顾客点了100杯奶茶,你在那算钱算5分钟,后面所有顾客都得等着,店直接就堵死了。对应到JS里,就是CPU密集型任务:比如100万次循环计算、大JSON解析、图片压缩、加密解密,这些任务放在主线程跑,直接就会导致:事件循环停转,所有异步回调都没法执行页面渲染卡住,白屏、掉帧用户点击、滑动完全没反应这时候就需要用户可控的多线程了:浏览器有Web Worker,Node.js有Worker Threads,都是干这个的——把这些耗CPU的计算任务丢给单独的线程跑,主线程该干嘛干嘛,算完了把结果传回来就行。Web Worker的本质是什么?很多人以为Web Worker是什么黑科技,其实就是一个独立的JS运行环境:每个Worker都是操作系统分配的独立线程,和主线程完全并行有自己独立的V8实例、独立的内存空间、独立的事件循环和主线程完全隔离,不能共享变量,不能访问DOM、window这些主线程的东西唯一的通信方式就是postMessage发消息,底层把数据复制一份传过去就相当于你给后厨单独开了个操作台,他在那自己做奶茶,做好了喊你一声,你递给他的材料都是复制一份给他,他那边改了不影响你这边的材料,从根源上避免冲突。浏览器里除了最常用的普通Worker,还有两种特殊Worker:SharedWorker:多个标签页可以共用同一个Worker,比如几个标签页共享一个WebSocket连接,不用每个页都开一个ServiceWorker:后台常驻的线程,就算你把网页关了它还能跑,用来做离线缓存、消息推送这些Node.js里的两套线程模型Node.js比浏览器多一层,有两套完全独立的线程池,很多人搞混:libuv底层线程池:这个是Node自带的,你平时用的fs读文件、dns解析、crypto加密,全都是丢给这个线程池跑的,你写代码的时候感知不到,它默认开4个线程,专门处理系统层面的阻塞IO操作,不跑你的业务JS代码。Worker Threads:这个和浏览器的Web Worker是一个东西,专门给你跑业务JS里的CPU密集任务的,独立V8实例,和主线程并行,Node里还支持共享内存,通信比浏览器更方便。一句话区分:libuv线程池是Node自带的后厨,专门做系统层面的杂活;Worker Threads是你自己雇的员工,专门帮你做业务里的重计算。三、线程池原理:为什么不能想开多少线程就开多少?很多人第一次接触多线程的时候会想:那我多开点线程不就快了?来一个任务开一个线程,岂不是美滋滋?要是真这么干,你的程序直接就崩了。这就是为什么要有线程池。3.1 开一个线程的成本比你想的大得多你以为开线程就是new一下的事?实际上创建一个操作系统线程是非常重的操作:内核开销:创建线程要进内核态,分配内核栈、线程ID、进程控制块,这个开销比普通函数调用大上千倍内存开销:每个线程默认要占1M左右的栈内存,你开1000个线程就是1G内存,直接就OOM了CPU上下文切换开销:CPU核心数是有限的,你电脑一般也就4核8核,开几十上百个线程,CPU根本忙不过来,要不停在不同线程之间切换,每次切换都要保存寄存器、栈、程序计数器,切换开销占了一半以上的时候,反而比单线程还慢。就像奶茶店,你本来就10平米的店,你雇20个后厨,人挤人转都转不开,不仅做不快,还容易出事,房租(内存)还贵死。3.2 线程池到底是个什么东西?线程池的思路特别简单:提前雇固定数量的员工,任务来了排队,谁闲下来谁做,做完一个接下一个,不随便招人也不随便裁人。本质上就是三个部分:固定数量的工作线程:一开始就创建好N个线程,一直跑着循环等任务,不随便销毁任务队列:所有要执行的任务先丢到队列里排队,先进先出调度逻辑:哪个线程闲下来了,就从队列里拿第一个任务给它做,做完了再拿下一个这样做的好处太明显了:不用频繁创建销毁线程,省了大量开销线程数量固定,不会把内存占满,也不会把CPU切换搞崩任务来了直接用空闲线程,不用等线程创建,响应更快所有线程统一管理,出问题好处理3.3 线程池是怎么调度任务的?工业级的线程池调度逻辑基本都是一样的,我们简单说下原理:来新任务了,如果现在闲的线程够,直接给空闲线程做如果线程都在忙,就把任务丢到队列里排队如果队列也满了,就临时多开几个线程帮忙(最多开到设置的最大值)如果线程数已经到最大值了还忙不过来,就触发拒绝策略(直接报错、丢任务、让提交任务的线程自己做等等)等忙完了,临时开的线

相关新闻

2026江南程序设计竞赛联盟暑期多校第一场_补题题解

2026江南程序设计竞赛联盟暑期多校第一场_补题题解

A 构造的芙莉莲题目分析: 题目给了我们两个长度均为 n 的排列数组,一个是原数组 a,一个是目标数组 b,要求我们利用异或运算在不超过 3*n 次的操作下,判断是否可以将 a 数组转化为 b 数组。可以则输出Yes,并…

2026/10/6 18:56:44 阅读更多 →
Flask-PyMongo扩展开发:如何自定义BSON转换器

Flask-PyMongo扩展开发:如何自定义BSON转换器

Flask-PyMongo扩展开发:如何自定义BSON转换器 【免费下载链接】flask-pymongo PyMongo support for Flask applications 项目地址: https://gitcode.com/gh_mirrors/fl/flask-pymongo Flask-PyMongo是一个为Flask应用提供PyMongo支持的强大扩展,它…

2026/10/7 4:14:28 阅读更多 →
Python 学习笔记:Python 里所有运算符

Python 学习笔记:Python 里所有运算符

前言上课整理了 Python 里面会用到的运算符,分成算术、赋值、比较、逻辑和其他运算符一、算术运算符就是平时做加减乘除计算用的符号。代表相加,10 加 3 结果是 13-代表相减,10 减 3 结果是 7*代表相乘,10 乘 3 结果是 30/ 代表普…

2026/10/13 1:22:13 阅读更多 →

最新新闻

5G-A通感融合能力开放:NEF架构、接口与信令流程详解

5G-A通感融合能力开放:NEF架构、接口与信令流程详解

简介:这份文档资料聚焦5G-A阶段通信感知融合的能力开放技术,面向通信领域研究者、核心网工程师及高校相关专业师生,帮助读者系统理解通感一体化从架构设计到业务落地的完整脉络。资源包内含1个docx文档,大小约151KB,内…

2026/10/13 19:40:25 阅读更多 →
YOLOv8人脸表情识别训练避坑指南:从数据集到推理部署

YOLOv8人脸表情识别训练避坑指南:从数据集到推理部署

简介:YOLOv8算法人脸表情识别训练权重与配套数据集组成一套可直接上手的目标检测训练资源,面向计算机视觉开发者和算法学习者,适用于人机交互、课堂专注度分析、驾乘安全监测等需要判断人物情绪状态的场景,也适合作为相关课题演示…

2026/10/13 19:40:25 阅读更多 →
恶意加密流量检测:深度学习与特征筛选完整源码实战

恶意加密流量检测:深度学习与特征筛选完整源码实战

简介:基于深度学习的恶意加密流量检测系统是一份完整的Python毕业设计源码与文档资料,面向信息安全方向的高校学生,可用于课程设计、期末大作业或毕设答辩。项目覆盖恶意加密流量识别的数据预处理、特征筛选、模型训练、结果分析与可视化展示…

2026/10/13 19:40:25 阅读更多 →
MQL5 通过 libmysql.dll 访问 MySQL:从环境配置到批量写入的完整实践

MQL5 通过 libmysql.dll 访问 MySQL:从环境配置到批量写入的完整实践

简介:这份文档资料面向使用 MetaTrader 平台进行量化开发的程序员,聚焦 MQL5(MQL4)无法直接与数据库交互这一痛点,讲解如何借助接口库访问 MySQL 数据库。内容围绕 MQLMySQL.mqh、MQLMySQL.dll 与 libmysql.dll 三层结…

2026/10/13 19:40:25 阅读更多 →
EJB入门项目实战:三类Session Bean与JNDI部署避坑指南

EJB入门项目实战:三类Session Bean与JNDI部署避坑指南

简介:这是一份面向EJB初学者的入门实践项目,基于IDEA与JBoss 7.1.1应用服务器,覆盖无状态/有状态会话Bean、实体Bean与消息驱动Bean的搭建与部署,适合正在学习Java EE组件化开发、希望理解EJB生命周期与事务控制的读者。压缩包共4…

2026/10/13 19:40:25 阅读更多 →
Nano Banana 2.1降价背后:API账单未减半的三大原因

Nano Banana 2.1降价背后:API账单未减半的三大原因

Nano Banana 2.1降价了,价格直接腰斩。按常理想,原来一个月花100元的API调用费,现在应该50元就够了。可我这几个月盯着账单数据,发现事情远没有这么简单——有些月份总花费只降了10%出头,甚至有一个周五的峰值账单比降…

2026/10/13 19:39:21 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →