1. 程式人生 > >js模擬java同步鎖

js模擬java同步鎖

有這方面知識的朋友,看到題目會認為,你這樣做沒有意義的,因為script指令碼永遠不會產生併發。確實指令碼執行是單執行緒的,即使有setTimeout、setInterval等方法,他也永遠不會產生併發。所以這裡只是模擬。

  說明一下應用場景,線上考試系統有自動交卷和手工交卷,結構大致如下

function handInAuto(){

    doHandIn();

}

function handInMan(){

    doHandIn();

}

function doHandIn(){

    ...

}

  我們通常可以在doHandIn方法中,取消定時時鐘,並且遮蔽手動的按鈕,這樣就不會重複執行doHandIn。或者在handInAuto遮蔽手動按鈕,在handInMan中取消時鐘,也可以。

  但總感覺不完美,交卷邏輯摻雜著控制邏輯。就不能像java那樣嗎?用關鍵字宣告就可以了。

public synchronized void doHandIn(){

    ...

}

   終於實現成如下形式,在程式碼塊外加個jsynchronized("handIn")判斷語句。每次呼叫會鎖定一定的時間,從而達到不會連續被執行的目的。

function doHandIn(){

    if(jsynchronized("handIn")){

        ...

    }

}

  實現程式碼

/**

 * js實現同步鎖,預設鎖定10秒

 * 示例

 * if(jsynchronized("handIn")){

        ...

 * }

 */

var locks = [];

var LOCKTIME_DEFAULT = 1000 * 10;

function jsynchronized(lockName,lockTime){

       if(getLock(lockName)){

              return false;

       }else{

              setLock(lockName,true);

              setTimeout(function(){

                     setLock(lockName,false);

              },lockTime?lockTime:LOCKTIME_DEFAULT);

              return true;

       }

}

/**

 * 獲得一個鎖,如果沒有新增這個鎖

 */

function getLock(lockName){

       for(var i = 0 ; i < locks.length ; i ++){

              if(locks[i][0] == lockName){

                     return locks[i][1];

              }

       }

       locks[locks.length] = [lockName,false];

       return false;

}

/**

 * 設定一個鎖,如果沒有新增這個鎖

 */

function setLock(lockName,lockValue){

       for(var i = 0 ; i < locks.length ; i ++){

              if(locks[i][0] == lockName){

                     locks[i][1] = lockValue;

                     return ;

              }

       }

       locks[locks.length] = [lockName,lockValue];

}

  這裡的"handIn"引數,根據不同的功能區別開就可以了。

  是不是感覺有點像java的synchronized?