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?