號外: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方法創建一個新的線程
newThread方法接受一個匿名函數,我們可以看到在這個匿名函數體內部,包含了獨立線程塊自己的資源,變量a/b,以及自己的邏輯
$kit.multithread.iterate方法提供一個循環方法,類似while,接受2個參數,參數1為一個是否執行循環的標記,參數2為一個循環體。
我們可以看到線程1的循環體的意思就是一個死循環,不斷的輸出“數字a為xxx”這樣的文字
在循環體內部,有一個sleep方法,是讓程序塊休眠指定的時間,這里是100毫秒
線程2的意思就是b的遞減,輸出字段,然后有兩個判斷,當b<995,kill線程1,當b<980時kill自己
最后就是線程定義完畢之后,執行方法
運行頁面,我們就會看到線程1和線程2交織執行
(三)原理解析
查看kit源代碼,我們可以看到
新建一個線程,kit會保留線程的id號以及線程對應的匿名方法
運行比較簡單,直接執行
延時的實現,使用setTimeout做延時,這里有個技巧,在setTimeout里面用匿名方法糾正this指針,同時在線程的附屬信息里面記錄延時執行的stack順序
循環的實現,最為復雜,可以看到首先保留遠程執行方法的上下文,定義一個inner Fn執行第一次方法體,然后用setInterval執行后續,在setInterval內部還要加載對於sleep的延時判斷,如果當前excuteStack處於sleep狀態,那么繼續hold,等待sleep結束再繼續循環
殺死線程,清空所有的excuteStack里面的timeout,delete線程注冊信息
(四) 高級技巧
其實對於一個js程序塊來說,按照$kit提供的api改成這樣已經看上不去很不像一段簡單的js代碼了
如果要做的更友好一些,我們可以使用正則表達式做一個詞法分析器,通過fn.toString獲取function的代碼塊文本,分析,並轉換for語句,while語句成為$kit的iterate語句,直接轉換sleep(xxx);為$kit的sleep方法,這樣的代碼會寫的更友好一些,這里只為拋磚引玉,歡迎有興趣的同學繼續改成$kit的多線程類,這里也提供了一個parse方法,沒有實現