js单线程的理解
为什么js采用单线程
为了避免复杂性,比如操作DOM,会引起复杂的同步问题,故从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。
***为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。(还没有去研究过)
js单线程与异步的概念
js线程即javascript引擎线程,JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序,但是浏览器为耗时任务开辟了另外的线程,如GUI渲染线程,GUI事件触发线程,http请求线程,setTimeout等,将这些线程都会排列在主线程之外的任务队列,等待被执行,这就是异步的概念。
GUI事件触发线程:
JavaScript脚本的执行不影响html元素事件的触发,在t1时间段内,首先是用户点击了一个鼠标键,点击被浏览器事件触发线程捕捉后形成 一个鼠标点击事件,由图可知,对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理t1时的任务,这个鼠标 点击事件正在等待处理.在JavaScript引擎运行脚本期间,浏览器渲染线程都是处于挂起状态的,也就是说被”冻结”了.
所以,在脚本中执行对界面进行更新操作,如添加结点,删除结点或改变结点的外观等更新并不会立即体现出来,这些操作将保存在一个队列中,待JavaScript引擎空闲时才有机会渲染出来.
GUI事件触发线程:
JavaScript脚本的执行不影响html元素事件的触发,在t1时间段内,首先是用户点击了一个鼠标键,点击被浏览器事件触发线程捕捉后形成 一个鼠标点击事件,对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理t1时的任务,这个鼠标 点击事件正在等待处理.
定时触发线程:
注意这里的浏览器模型定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,如果处于阻塞线程状态就计不了时,它必须依赖外部来计时并触发定时,所以队列中的定时事件也是异步事件.
setTimeout(function(){console.log(1);},0); //主线程执行完立即执行
setTimeout(function(){
/* Some long block of code... */
setTimeout(arguments.callee, 10);
}, 10); //setTimeout回调函数的执行和上一次执行之间的间隔至少有10ms
setInterval(function(){
/* Some long block of code... */
}, 10); //如果setInterval回调函数的执行时间将足够长(比指定的时间间隔长),它们将连续执行并且彼此之间没有时间间隔。
*并发 并行 同步 多线程 异步的概念
并发与并行:进程与进程之间的关系
1.并发: 在操作系统中,同一时间段内有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。并发的程序中有同步和互斥两种关系;
a.同步:进程之间的关系不是相互排斥临界资源的关系,而是相互依赖的关系,即前一个进程的输出作为后一个进程的输入,当第一个进程没有输出时第二个进程必须等待。具有同步关系的一组并发进程相互发送的信息称为消息或事件。
b.互斥:进程间相互排斥的使用临界资源的现象。
2.并行:在单处理器系统中的并发进程被交替执行,即伪并发,在多处理器系统中的并发程序重叠执行,即真并发,即并行。故并行是同时发生的多个并发事件,具有并发的含义,但并发不一定并行,也亦是说并发事件之间不一定要同一时刻发生。
多线程
多线程是程序设计的逻辑层概念,它是进程中并发运行的一段代码,多线程可以实现线程间的切换执行。
线程的同步与异步
异步和同步是相对的,同步是顺序执行,执行完一个再执行下一个,需要等待,协调运行。异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作,线程是实现异步的一个方式,异步让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程干其他的事情。而主线程即同步顺序执行的。
*异步和多线程并不是一个同等关系,异步是最终目的,多线程只是我们执行异步的一种手段。异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其他的事情。实现异步可以采用多线程或则交给另外的进程来处理。