纸头折飞机
欢迎大家加入KitJs官方高级QQ群88093625,讨论前端技术,上海携程招聘H5,iOS,android,产品,设计,交互,测试,有意者发简历到xueduanyang1985@163.com

号外:kitjs官方讨论QQ群建立了,QQ群号88093625,欢迎大家加入,讨论前端相关话题

今天给大家介绍一下kitJs的多线程类,以及原生的javascript,不借助浏览器插件以及HTML5的webWorker是如何实现多线程模式的。

Demo地址:http://xueduany.github.com/KitJs/KitJs/index.html#multithread

(一)多线程简单工作原理

所谓多线程,一般意义上理解,就是两段程序块,在操作系统的分时调配下,交错运行。

1. 每个程序块需要有自己独立的线程运行环境以及独立上下文

2. 每个程序块包含多个语句块,每个语句块是原子的,不可分割的,例如while之类的循环

3. 语句块和语句块之间是可以分割执行的,以及支持sleep,比如a=1;b=2;这样是两个语句块

4. 程序块可以调用公共资源区,比如调用window空间下其他资源

5. 支持死循环解锁,即杀死进程

(二)Kit是如何实现的

首先我们通过$kit.multithread.newThread方法创建一个新的线程

image

newThread方法接受一个匿名函数,我们可以看到在这个匿名函数体内部,包含了独立线程块自己的资源,变量a/b,以及自己的逻辑

$kit.multithread.iterate方法提供一个循环方法,类似while,接受2个参数,参数1为一个是否执行循环的标记,参数2为一个循环体。

image

我们可以看到线程1的循环体的意思就是一个死循环,不断的输出“数字a为xxx”这样的文字

在循环体内部,有一个sleep方法,是让程序块休眠指定的时间,这里是100毫秒

image

线程2的意思就是b的递减,输出字段,然后有两个判断,当b<995,kill线程1,当b<980时kill自己

 

最后就是线程定义完毕之后,执行方法

image

运行页面,我们就会看到线程1和线程2交织执行

image

(三)原理解析

查看kit源代码,我们可以看到

 

 

 

 

image

新建一个线程,kit会保留线程的id号以及线程对应的匿名方法

image

运行比较简单,直接执行

image

延时的实现,使用setTimeout做延时,这里有个技巧,在setTimeout里面用匿名方法纠正this指针,同时在线程的附属信息里面记录延时执行的stack顺序

image

循环的实现,最为复杂,可以看到首先保留远程执行方法的上下文,定义一个inner Fn执行第一次方法体,然后用setInterval执行后续,在setInterval内部还要加载对于sleep的延时判断,如果当前excuteStack处于sleep状态,那么继续hold,等待sleep结束再继续循环

image

杀死线程,清空所有的excuteStack里面的timeout,delete线程注册信息

(四) 高级技巧

其实对于一个js程序块来说,按照$kit提供的api改成这样已经看上不去很不像一段简单的js代码了

如果要做的更友好一些,我们可以使用正则表达式做一个词法分析器,通过fn.toString获取function的代码块文本,分析,并转换for语句,while语句成为$kit的iterate语句,直接转换sleep(xxx);为$kit的sleep方法,这样的代码会写的更友好一些,这里只为抛砖引玉,欢迎有兴趣的同学继续改成$kit的多线程类,这里也提供了一个parse方法,没有实现

posted on 2012-05-30 15:30  薛端阳  阅读(4375)  评论(3编辑  收藏  举报