javascript没有多线程,所以也不存在多线程同时运行的说法。平时写代码的时候需要考虑尽量避免线程阻塞。
成都创新互联公司-专业网站定制、快速模板网站建设、高性价比洮南网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式洮南网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖洮南地区。费用合理售后完善,十年实体公司更值得信赖。
比较好的方法就是尽量使用异步+回调的方式进行处理。
一、线程和进程基本概念
进程:操作系统分配的占有CPU资源的最小单位。拥有独立的地址空间。
线程:安排CPU执行的最小单位。同一个进程下的所有线程,共享进程的地址空间。
简单讲,计算机就像工厂,进程是个大车间,计算机内部有很多个这样的大车间。线程是工人,每一个车间里的工人至少有一个。
为什么这么画呢?有点一个挨一个的效果呢?是因为以前我就老是疑惑进程或者线程运行时到底是并行?还是串行?
其实,在单CPU或单核的情况下,宏观上无论是进程也好,线程也罢,都是并行的。而在微观下,某一个具体的时刻,他们实际上都是串行的。在多CPU或多核的情况下,才是真正意义的并行。
二、线程和进程的关系、通性
关系:进程中包含着至少一个线程。在进程创建之初,就会包含一个线程,这个线程会根据需要,调用系统库函数去创建其他线程。但需要注意的是,这些线程之间是没有层级关系的,他们之间协同完成工作。在整个进程完成工作之后,其中的线程会被销毁,释放资源。
通性:都包含三个状态,就绪、阻塞、运行。通俗的讲,阻塞就是资源未到位,等待资源中。就绪,就是资源到位了,但是CPU未到位,还在运行其他。
三、线程的好处
既然,线程和进程是存在通性的,那么为什么操作系统还要设置线程这个单位,那就说说线程的几点好处:
1、在一个程序中,多个线程可以同步或者互斥并行完成工作,简化了编程模型;
2、线程较进程来讲,更轻;
3、线程虽然微观并行。但是,在一个进程内部,一个线程阻塞后,会执行这个进程内部的其他线程,而不是整体阻塞。从某种意义上,提高了CPU的利用率。
四、市面上的通用叫法
单线程与多线程,都指在一个进程内的单和多。不要笑我,之前真的不懂。心中那只小羊驼,奔过来,跑过去。还抬起了傲娇的眼睛,看了我一眼,呵呵~~~
五、javaScript单线程执行机制
1、 首先解释下,单线程和多线程。
什么是单线程?单线程就是一个进程中只有一个线程。程序顺序执行,前面的执行完,才会执行后面的程序。
什么是多线程?多线程就是一个进程中只有多个线程。在进程内部进行线程间的切换,由于每个线程执行的时间片很短,所以在感觉上是并行的。
2、那么为什么感觉上javaScript是多线程?而且还支持AJAX异步呢?AJAX是真正的异步吗?
先说明,从哪里可以得出javaScript是单线程。比如你页面一上来就alert(“hello world~”);只要你不关闭这个对话框,后续的js代码就不会再执行。因为,单线程就是这样一步一步的顺次执行,前面不执行完,后面不会执行。也就是说,在具体的某一时刻,只有一段代码在执行。
可是,JavaScript明明可以处理各种触发事件,感觉上是异步多线程啊。其实,它的原理是这样的,JavaScript单线程的执行浏览器的一个事件队列,要执行的函数和触发事件的回调函数都被放在这个队列中。比如,我点击率一下按钮,之后又将浏览器缩小了,那么这两个事件的回调函数就会顺次地被放在当前执行的“函数”之后,再一一执行。
那么,既然JavaScript是单线程,那么如何维护这个函数队列呢,他分身无术啊。这时候,就需要知道,浏览器可不是单线程。虽然,每一个window只有一个js引擎,但是浏览器是事件驱动的、异步的、多线程的。
浏览器内部有一个事件轮询(event loop),是一个大的内部消息循环,会轮询大的消息队列,并执行。也就是js要处理的事件队列,是浏览器维护的。
浏览器至少有四个线程(不同浏览器会有差异): js引擎线程、界面渲染线程、浏览器事件触发线程、http请求线程。
其实,到这里就说的很明白了。但是,又想到了延时函数(setTimeout)的例子,感觉上,因为没有阻塞执行,会感觉是异步,其实并不是。只是,js在执行到延时函数时,会触发浏览器的定时器,到设置时间,浏览器再将这个函数放入执行的函数队列,再由JavaScript引擎执行。都是在浏览器空闲了才会执行。
关于AJAX的异步,是真正的异步。同样的道理,在调用AJAX的时候,浏览器会开辟一个新的线程,去处理这个请求,得到响应后,如果这个请求有回调,会将这个回调再放入事件队列中。再由JavaScript引擎执行。
3、关于JavaScript的阻塞
浏览器虽然是多线程,但是由于JavaScript具有阻塞特性,无论外链还是内嵌脚本,在浏览器执行解释js脚本的时候,浏览器是不会去做别的事情的,比如渲染页面,而是直到js下载并执行完毕。
这样,js脚本的下载、解释执行,会反该页面的继续绘制,给用户带来不良的体验。所以,要对其优化,有如下几点:
a、将script内嵌和外链,在可以的情况下,放在body底部。注:对于css,浏览器是并行下载
b、在页面onload后,加载js
c、html5 script标签的defer属性,在页面加载完成后下载
d、使用创建script标签的方式,在页面加载完成后添加进去。
注:解决阻塞就是一句话,先让页面渲染完,再加载js。
六、Node.js单线程执行机制
脑子就像有问题一样。js都是单线程的了,node.js就是js实现的,还能是多线程?!!呵呵哒~
Node.js其实还不是真正意义上的js,他是借用了js语法实现的,达到真正意义的非阻塞服务端语言。但是他的运行机制,也是事件轮询 (Event Loop)。
不可以的,JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序。
可以参考下面的文章:
零基础学习java可按照这份大纲来进行学习
第一阶段:Java专业基础课程
阶段目标:
1. 熟练掌握Java的开发环境与编程核心知识
2. 熟练运用Java面向对象知识进行程序开发
3. 对Java的核心对象和组件有深入理解
4. 熟练应用JavaAPI相关知识
5. 熟练应用JAVA多线程技术
6. 能综合运用所学知识完成一个项目
知识点:
1、基本数据类型,运算符,数组,掌握基本数据类型转换,运算符,流程控制。
2、数组,排序算法,Java常用API,类和对象,了解类与对象,熟悉常用API。
3、面向对象特性,集合框架,熟悉面向对象三大特性,熟练使用集合框架。
4、IO流,多线程。
5、网络协议,线程运用。
第二阶段:JavaWEB核心课程
阶段目标:
1. 熟练掌握数据库和MySQL核心技术
2. 深入理解JDBC与DAO数据库操作
3. 熟练运用JSP及Servlet技术完成网站后台开发
4. 深入理解缓存,连接池,注解,反射,泛型等知识
5. 能够运用所学知识完成自定义框架
知识点:
1、数据库知识,范式,MySQL配置,命令,建库建表,数据的增删改查,约束,视图,存储过程,函数,触发器,事务,游标,建模工具。
2、深入理解数据库管理系统通用知识及MySQL数据库的使用与管理。为Java后台开发打下坚实基础。Web页面元素,布局,CSS样式,盒模型,JavaScript,jQuery。
3、掌握前端开发技术,掌握jQuery。
4、Servlet,EL表达式,会话跟踪技术,过滤器,FreeMarker。
5、掌握Servlet相关技术,利用Servlet,JSP相关应用技术和DAO完成B/S架构下的应用开发。
6、泛型,反射,注解。
7、掌握JAVA高级应用,利用泛型,注解,枚举完成自己的CRUD框架开发为后续框架学习做铺垫。
8、单点登录,支付功能,项目整合,分页封装熟练运用JSP及Servlet核心知识完成项目实战。
第三阶段:JavaEE框架课程
阶段目标:
1. 熟练运用Linux操作系统常见命令及完成环境部署和Nginx服务器的配置
2. 熟练运用JavaEE三大核心框架:Spring,SpringMVC,MyBatis
3. 熟练运用Maven,并使用SpringBoot进行快速框架搭建
4. 深入理解框架的实现原理,Java底层技术,企业级应用等
5. 使用Shiro,Ztree和Spring,SpringMVC,Mybaits完成企业项目
知识点:
1、Linux安装配置,文件目录操作,VI命令,管理,用户与权限,环境部署,Struts2概述,hiberante概述。
2、Linux作为一个主流的服务器操作系统,是每一个开发工程师必须掌握的重点技术,并且能够熟练运用。
3、SSH的整合,MyBatis,SpringMVC,Maven的使用。
4、了解AOP原理,了解中央控制器原理,掌握MyBatis框架,掌握SSM框架的整合。
5、Shiro,Ztree,项目文档,项目规范,需求分析,原型图设计,数据库设计,工程构建,需求评审,配置管理,BUG修复,项目管理等。
6、独立自主完成一个中小型的企业级综合项目的设计和整体架构的原型和建模。独立自主完成一个大型的企业级综合项目,并具备商业价值
JS为我们提供了一个Worker的类,它的作用就是为了解决这种阻塞的现象。当我们使用这个类的时候,它就会向浏览器申请一个新的线程。这个线程就用来单独执行一个js文件。
var worker = new Worker(js文件路径);
1
那么这个语句就会申请一个线程用来执行这个js文件。
当然,在主线程中有一些方法来实现对新线程的控制和数据的接收。在这里,我们只说比较常用的几个方法。
1 //postMessage(msg);
2 //postMessage方法把在新线程执行的结果发送到浏览器的js引擎线程里
3 worker.onmessage = function(){
4
7 setTimeout( function(){
8 worker.terminate();
9 //terminate方法用于关闭worker线程
10 },2000)
11
12 setTimeout( function(){
13 worker = new Worker("js/test22.js");
14 //再次开启worker线程
15 },3000)
在新线程中使用postMessage()方法可以向主线程中发送一些数据,主线程中使用worker的onmessage事件来接收这些数据,这样就实现了js的多线程执行和多线程之间数据的传递。
因为JS运行在浏览器中,是单线程的,每个window一个JS线程,既然是单线程的,在某个特定的时刻只有特定的代码能够被执行,并阻塞其它的代码。而浏览器是事件驱动的(Event driven),浏览器中很多行为是异步(Asynchronized)的,会创建事件并放入执行队列中。javascript引擎是单线程处理它的任务队列,你可以理解成就是普通函数和回调函数构成的队列。当异步事件发生时,如mouse click, a timer firing, or an XMLHttpRequest completing(鼠标点击事件发生、定时器触发事件发生、XMLHttpRequest完成回调触发等),将他们放入执行队列,等待当前代码执行完成。