# 初识多线程与异步
前两天学习java到多线程就在思考多线程和javascript的异步有什么区别,经过上网搜寻资料,整理了这篇文章,如果文章有问题,恳请大家能与指出。
# 1. 第一个概念:进程与线程
一个程序就是一个进程,而一个程序中的多个任务则被称为线程。 进程就像是一家工厂,多个工厂之间是独立存在的。而线程就像是工厂中的那些工人,共享资源,完成同一个大目标。
# 2.异步是目的多线程是方法
异步和多线程有什么区别?异步是目的,而多线程是实现这个目的的方法。 异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回.实现异步可以采用多线程技术或则交给另外的进程来处理.异步是一种效果,多线程是一种具体技术。可以说,用“多线程”实现“异步”。
# 3.多线程和异步操作的异同
多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性,多线程是用来并发的执行多个任务。 若使用异步方式,用这些固定数目的线程在固定的时间内就可以服务更多的请求,而如果用同步方式,那么每个请求都自始至终占用这一个线程,服务器可以同时服务的请求数就少了。 当异步操作执行完成后,系统会从可用线程中选取一个执行回调程序,这时的这个线程可能是刚开始发出请求的那个线程,也可能是其他的线程,因为系统选取线程是随机的事情,所以不能说绝对不是刚开始的那个线程。
# 4.JavaScript的单线程
JavaScript 是一门动态的解释型的语言,具有跨平台性。JavaScript 从诞生起就是单线程,原因大概是不想让浏览器变得太复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一种网页脚本语言来说,这就太复杂了。 因此可以说javaScript引擎是单线程的,但是JavaScript 运行的宿主环境浏览器是多线程的。
# 5.浏览器的多线程
浏览器主线程常驻线程
- GUI 渲染线程
- 绘制页面,解析 HTML、CSS,构建 DOM 树,布局和绘制等
- 页面重绘和回流
- 与 JS 引擎线程互斥,也就是所谓的 JS 执行阻塞页面更新
- JS 引擎线程
- 负责 JS 脚本代码的执行
- 负责准执行准备好待执行的事件,即定时器计数结束,或异步请求成功并正确返回的事件
- 与 GUI 渲染线程互斥,执行时间过长将阻塞页面的渲染
- 事件触发线程
- 负责将准备好的事件交给 JS 引擎线程执行
- 多个事件加入任务队列的时候需要排队等待(JS 的单线程)
- 定时器触发线程
- 负责执行异步的定时器类的事件,如 setTimeout、setInterval
- 定时器到时间之后把注册的回调加到任务队列的队尾
- HTTP 请求线程
- 负责执行异步请求
- 主线程执行代码遇到异步请求的时候会把函数交给该线程处理,当监听到状态变更事件,如果有回调函数,该线程会把回调函数加入到任务队列的队尾等待执行
# 6.同步任务和异步任务
简单的介绍一下同步任务和异步任务的概念。
- 同步任务:必须等到结果来了之后才能做其他的事情,举例来说就是你烧水的时候一直等在水壶旁边等水烧开,期间不做其他的任何事情。
- 异步任务:不需要等到结果来了才能继续往下走,等结果期间可以做其他的事情,结果来了会收到通知。举例来说就是你烧水的时候可以去做自己想做的事情,听到水烧开的声音之后再去处理。
从概念就可以看出来,异步任务从一定程度上来看比同步任务更高效一些,核心是提高了用户体验。
# 7.异步是怎么实现的
看到这里,总算是进入正题了,先讲讲浏览器端的 Event Loop 是什么样的。 上图是一张 JS 的运行机制图,Js 运行时大致会分为几个部分:
- Call Stack:调用栈(执行栈),所有同步任务在主线程上执行,形成一个执行栈,因为 JS 单线程的原因,所以调用栈中每次只能执行一个任务,当遇到的同步任务执行完之后,由任务队列提供任务给调用栈执行。
- Task Queue:任务队列,存放着异步任务,当异步任务可以执行的时候,任务队列会通知主线程,然后该任务会进入主线程执行。任务队列中的都是已经完成的异步操作,而不是说注册一个异步任务就会被放在这个任务队列中。
具体讲解参看:Horace 的 https://juejin.im/post/5e80595c518825739f6af6f4
# 参考文章
[1]博客链接: https://tearill.github.io/ [2]Wikipedia: https://en.wikipedia.org/wiki/Event_loop [3]JS 大会: https://www.bilibili.com/video/BV1bE411B7ez?t=478 [4]github: https://github.com/tearill/Reading_Record [5]掘金: https://juejin.im/post/5e80595c518825739f6af6f4