JavaScript单线程运行机制与并发模型
来源:互联网 发布:加入网络作协要求 编辑:程序博客网 时间:2024/05/22 07:30
一、为什么JavaScript是单线程?
JavaScript语言的一大特点就是单线程,也就是说,同一时间只能做一件事。具体地,一个window对应一个JavaScript线程。
JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。
为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。
二、JavaScript并发模型与事件循环
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。那么JavaScript是如何实现异步调用的呢?
JavaScript里这种并发的一种理论上的模型如下:
(1)所有同步任务依次被执行,在内存栈区域产生相应的栈帧(活动记录)。
(2)一个JavaScript运行时包含一个待处理的消息队列,每个消息都与一个函数相关联。当栈为空时,就从队列中取出一个消息并进行处理。这个处理过程包含了调用与这个消息相关联的函数(以及因而创建了一个初始堆栈帧)。当栈再次为空的时候,也就意味着消息处理结束。
这种处理方式通常使用如下的方式来实现:
while(queue.waitForMessage()){ queue.processNextMessage();}如果当前没有任何消息,queue.waitForMessage会同步等待消息到来。
因此这个过程被称为事件循环。
每一个消息执行完成后,其他消息才会被执行。在浏览器里,当一个事件出现且一个事件监听程序被绑定时,消息会被随时添加,如果没有事件监听器,则事件丢失。调用setTimeout函数会在一个时间段过去后在队列中添加一个消息,这个时间段作为函数的第二个参数被传入。如果队列中没有其他消息,那么这个消息会被马上处理,但是如果有其他消息,则setTimeout消息必须等待其他消息处理完。因此第二个参数仅仅表示最少的时间而非确切的时间。
以Ajax为例,事件循环模型如下:
这里的Ajax线程不同于JavaScript执行线程。
- JavaScript单线程运行机制与并发模型
- JavaScript 运行机制与单线程
- javascript运行机制:并发模型 与Event Loop
- javaScript Core -- 运行机制:单线程&&任务队列
- JavaScript单线程模型
- 理解JavaScript的单线程运行机制及setTimeout(fn,0)
- Javascript学习笔记(单线程模型)
- 浏览器UI多线程及对JavaScript单线程底层运行机制的理解
- 浏览器UI多线程及对JavaScript单线程底层运行机制的理解
- PHP工作模型与运行机制
- PHP工作模型与运行机制
- PHP工作模型与运行机制
- PHP工作模型与运行机制
- Flash的运行机制:异步单线程
- Quartz 并发/单线程
- 单线程实现并发
- Quartz 并发/单线程
- JavaScript单线程的疑问与解答
- 适配器模式
- [PAT乙级]1070. 结绳(25)
- 求和符号(Σ,sigma)
- 支配集、覆盖集、独立集、匹配与着色
- Python的逻辑控制true/false和循环
- JavaScript单线程运行机制与并发模型
- Spring中Aware系列接口
- Python起步之利用Turtle进行时钟绘制
- MAC地址小知识
- Spring统一异常处理之@ControllerAdvice 无法使用问题
- NGUI学习笔记(八):图片(UISprite)灰化效果
- 20、顺时针打印矩阵
- 插件加载---之一
- Linux下使用getopt函数来获取传入的参数