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/7/24 9:51:05 阅读更多 →
【通过ADMM进行TV-L1去噪】一种用于总变差去噪的交替方向法研究附Matlab代码

【通过ADMM进行TV-L1去噪】一种用于总变差去噪的交替方向法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/7/24 8:46:11 阅读更多 →
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/7/21 14:49:11 阅读更多 →

最新新闻

10个Python+AI实战项目!告别教程小白,练出真本事

10个Python+AI实战项目!告别教程小白,练出真本事

是否还在依照教程去做猫狗识别、房价预测呢, 学完之后合上书本, 除了敲过几行代码之外, 什么核心技能都没有积攒下来吗, 想要真正掌握AI, 就必须从能够解决实际问题的项目着手, 这10个以上的AI实战项目, 覆盖了语音处理、文本分析、多模态应用等多个方向, 做完之后就能把AI技术…

2026/7/25 7:06:04 阅读更多 →
C++性能优化实战:从内存访问到并发编程的核心技巧

C++性能优化实战:从内存访问到并发编程的核心技巧

1. 项目概述:为什么C性能优化是程序员的必修课?在C的世界里,性能从来不是一个可选项,而是一个必选项。无论是开发高频交易系统、游戏引擎、数据库内核,还是嵌入式设备驱动,程序的运行速度直接决定了产品的竞…

2026/7/25 7:06:04 阅读更多 →
Mistral AI Connectors:企业级AI应用集成标准化与安全治理实践

Mistral AI Connectors:企业级AI应用集成标准化与安全治理实践

最近在调试一个企业级AI应用时,遇到了一个典型问题:团队需要让AI助手能够查询内部CRM数据,但每次调用都要处理复杂的OAuth认证、API限流和错误重试。更麻烦的是,不同团队重复实现了相似的集成逻辑,既浪费资源又带来安全…

2026/7/25 7:06:04 阅读更多 →
LinkSwift技术解析:如何通过JavaScript逆向工程实现九大网盘直链提取

LinkSwift技术解析:如何通过JavaScript逆向工程实现九大网盘直链提取

LinkSwift技术解析:如何通过JavaScript逆向工程实现九大网盘直链提取 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移…

2026/7/25 7:06:04 阅读更多 →
深度学习面部表情识别系统设计与优化实践

深度学习面部表情识别系统设计与优化实践

1. 项目背景与核心价值面部表情识别技术近年来在多个领域展现出巨大应用潜力。这个基于深度学习的Python实现方案,特别适合需要快速部署轻量级表情识别系统的开发者。我在实际安防和人机交互项目中多次采用类似架构,其核心优势在于平衡了准确率和实时性。…

2026/7/25 7:06:04 阅读更多 →
YOLOv11在手机缺陷检测中的工业应用与优化

YOLOv11在手机缺陷检测中的工业应用与优化

1. 项目概述:当YOLOv11遇上手机检测去年帮某电子厂做产线质检系统时,我第一次把YOLOv5部署到手机外壳缺陷检测场景。当时产线主管指着误检的样品问我:"能不能把识别准确率再提高5个百分点?"这个需求直接促成了我对YOLOv…

2026/7/25 7:05:04 阅读更多 →

日新闻

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决您的…

2026/7/25 0:00:35 阅读更多 →
C++ string类模拟实现:从深拷贝到内存管理的完整指南

C++ string类模拟实现:从深拷贝到内存管理的完整指南

1. 项目概述:为什么我们要“手撕”string类?在C的学习道路上,尤其是从C语言过渡到C的“初阶”阶段,string类绝对是一个绕不开的核心。标准库里的std::string用起来太方便了,、find、substr,几个操作符和函数…

2026/7/25 0:00:35 阅读更多 →
三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

1. 先搞清楚“三角洲寻宝鼠”到底是什么工具从名称来看,“三角洲寻宝鼠”更像是一个资源查找或文件检索类工具,而不是游戏或娱乐软件。这类工具的核心价值在于帮助用户快速定位特定资源,比如文档、图片、压缩包或特定格式的文件。如果你经常需…

2026/7/25 0:00:35 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/25 5:08:22 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/25 5:13:53 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 18:52:18 阅读更多 →

月新闻