javascript中的線程之我見

今天與一個同事爭論javascripe中間的線程機制,他爭論說javascript是有線程的,理由即便javascript中間的事件回調就是線程的實現,我的認爲在javascript中是沒有線程機制的

理由以下: javascript

引自《精通javascript》 john resig著: css

<script>
  while(!window.loaded);
  //some operation 
   window.alert();
</script>

    這段代碼的意圖就是想阻塞當前js線程, 直到頁面徹底加載完畢才執行後續操做。可是獲得的效果倒是瀏覽器暫停或者假死,可見在js中是不能用循環來暫停等待的。要實現這個效果必須採用回調: html

wndow.onload=funcrion(){
//some operation
}


    然而回調不是js語言中支持多線程的依據。咱們知道在windows中的回調消息機制是這樣的:
windows把單擊事件和一個處理函數關聯起來,當咱們點擊了某個按鈕的時候,系統會調用這個單擊事件的處理函數。實際上,windows內部會維護一張事件處理表,這個表中單擊事件對應一個處理函數的函數指針。當點擊事件發生時,windows會調用這個函數指針所指向的函數。 java

    那什麼是線程? 我想咱們應該從支持多線程的操做系統提及。多線程就是讓多個計算過程交替執行而且這個交替的時間片很短,短到咱們沒法感知。這就是爲何單處理器也能夠併發執行線程。操做系統會維護多個狀態的線程隊列,並決定採起何種調度算法來切換線程之間的執行.   算法

    js中沒有線程的概念,或者說全部的操做到放在同一個線程(即單線程)中。那麼應該如何來模擬這個線程機制呢。既然js引擎沒有爲咱們維護一個線程列表,那麼咱們本身來實現(這個線程列表和調度算法):
windows

<script language="javascript">
    var thread_one_time=0;
    var thread_two_time=0;
    function thread_one(){
        thread_one_time++;    
        alert( thread_one_time);
    }
     
    function thread_two(){
        thread_two_time++;
        alert( thread_two_time);
    }   
    setInterval(thread_one,100);
    setInterval(thread_two,100);
    
    for (var i =0; i< 10; i++){
       alert('主線程: '+i);
    }
</script>

在這裏,咱們就能夠看見兩個子程序交替執行了,其實,若是用線程的眼光看的話,這裏是有三個線程的,一個是thread_one 一個是thread_two一個是main_thread(不過它先執行完)。這裏的主線程能夠當作操做系統中的進程(線程)管理器,由它來調度、切換和管理整個系統的線程。這裏main採用的」調度算法「很樸實,就是100秒的時間片輪轉,沒有優先級,沒有中斷。

    下面給出一個完整的線程管理器例子:
瀏覽器

thread.js:  多線程

/**
 * 線程管理類
 * @param _task 任務函數
 * @param _delay 間隔時間(單位毫秒)
 * @param _times 執行次數(-1表示永遠執行)
 * @author zxub 2006-06-12
 */
function Thread(_task,_delay,_times)
{
    this.runFlag=false;
    this.busyFlag=false;
    this.taskArgs=Array.prototype.slice.call(arguments,3);
    
    if (_times!=undefined)
    {
        this.times=_times;
    }
    else
    {
        this.times=1;
    }
    
    var _point=this;
    
    this.timerID=-1;
    
    this.start=function()
    {
        if (this.runFlag==false)
        {
            this.timerID=window.setInterval(_point.run,_delay);            
            this.runFlag=true;
        }
    }
    
    this.run=function()
    {
        if (_point.busyFlag){
		   return;
        }else if (_point.times==-1){
            _task(_point.taskArgs);
        }else if (_point.times>0){
            _task(_point.taskArgs);
            _point.times-=1;
            if (_point.times==0){
                window.clearInterval(this.timerID);
            }                                  
        }        
    }
    
    this.sleep=function()
    {
        this.busyFlag=true;
    }
    
    this.resume=function()
    {
        this.busyFlag=false;
    }
    
    this.abort=function()
    {        
        window.clearInterval(this.timerID);        
    }
}

thread.html: 併發

<html>
<head>
<title>測試</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="thread.js"></script>    
<style type="text/css">
<!--
body,tr,td { font-size: 12px;}
-->
</style>
</head>
<body>
<script>
var func=function(_o)
{
    document.getElementById(_o).innerHTML=parseInt(document.getElementById(_o).innerHTML)+1;
}
var t1=new Thread(func,50,121,"t1");
var t2=new Thread(func,200,20,"t2");
</script>
<input type="button" value="start1" onclick='t1.start();'></input>
<input type="button" value="sleep1" onclick='t1.sleep();'></input>
<input type="button" value="resume1" onclick='t1.resume();'></input>
<input type="button" value="abort1" onclick='t1.abort();'></input>
<input type="button" value="start2" onclick='t2.start();'></input>
<input type="button" value="sleep2" onclick='t2.sleep();'></input>
<input type="button" value="resume2" onclick='t2.resume();'></input>
<input type="button" value="abort2" onclick='t2.abort();'></input>
<div id="t1">0</div> | <div id="t2">0</div>
<input type="button" value="t1.timerID" onclick='alert(t1.timerID);'></input>
<input type="button" value="t2.timerID" onclick='alert(t2.timerID);'></input>
</body>
</html>
相關文章
相關標籤/搜索