如下為簡單實現
介面定義:
public
inte***ce
distributedlock
extends
remoteobject
介面實現
public
class
distributedlockimpl
extends
unicastremoteobject
implements
distributedlock
/***@param locktimeout 鎖超時時間,如果加鎖的物件不解鎖,超時之後自動解鎖
*@param locktimeoutunit
*@throws remoteexception
*/public
distributedlockimpl(long locktimeout, timeunit locktimeoutunit) throws remoteexception
public
long
lock() throws timeoutexception
private
boolean
islocktimeout()
return (system.currenttimemillis() - beginlocktime) < locktimeoutunit.tomillis(locktimeout);
}private
long
gettoken()
public
long
trylock(long time, timeunit unit) throws timeoutexception
}thread.sleep(1);
} catch (interruptedexception e)
}return gettoken();}}
public
void
unlock(long token) else
}}
上面的**提供了,永遠等待的獲取鎖的lock方法和如果在指定的時間獲取鎖失敗就獲得超時異常的trylock方法,另外還有乙個unlock方法。
技術的關鍵點實際上就是在token上,上面的實現,有乙個基本的假設,就是兩次遠端呼叫之間的時間不可能在1納秒之內完成。因此,每次鎖的操作都會返回乙個長整型的令牌,就是當時執行時間的納秒數。下次解鎖必須用獲得的令牌進行解鎖,才可以成功。如此,解鎖就不用新增同步操作了,從而解決掉lock和unlock都加了synchronize關鍵字死鎖的問題。
實際上,沒有令牌也是可以的,但是那樣就會導致a獲取了鎖,但是b執行unlock也會成功解鎖,是不安全的,而加入令牌,就可以保證只有加鎖者才可以解鎖。
測試**如下:
public
class
testdlock
long s = system.currenttimemillis();
processor.start();
long e = system.currenttimemillis();
system.out.println(e - s);
rmiserver.unexportobject(distributedlock);
}}class
runlock
extends
abstractprocessor
@override
protected
void action() throws exception
system.out.println("end-" + thread.currentthread().getid());
} catch (remoteexception e)
}}
執行結果如下:
-0 [main] info - 執行緒組執行開始,執行緒數8...
-3 [aa-aa0] info - 執行緒執行開始...
-3 [aa-aa1] info - 執行緒執行開始...
-3 [aa-aa2] info - 執行緒執行開始...
-3 [aa-aa3] info - 執行緒執行開始...
-3 [aa-aa4] info - 執行緒執行開始...
-4 [aa-aa5] info - 執行緒執行開始...
-4 [aa-aa6] info - 執行緒執行開始...
-8 [aa-aa7] info - 執行緒執行開始...
end-19
-9050 [aa-aa3] info - 執行緒執行結束
end-17
-9052 [aa-aa1] info - 執行緒執行結束
end-20
-9056 [aa-aa4] info - 執行緒執行結束
end-16
-9058 [aa-aa0] info - 執行緒執行結束
end-21
-9059 [aa-aa5] info - 執行緒執行結束
end-26
-9063 [aa-aa7] info - 執行緒執行結束
end-18
-9064 [aa-aa2] info - 執行緒執行結束
end-22
-9065 [aa-aa6] info - 執行緒執行結束
-9066 [main] info - 執行緒組執行結束, 用時:9065ms
9069
也就是9069ms中執行了8000次鎖定及解鎖操作。
小結:上面的分布式鎖實現方案,綜合考慮了實現簡單,鎖安全,鎖超時等因素。實際測試,大概900到1000次獲取鎖和釋放鎖操作每秒,可以滿足大多數應用要求。
參考博文:
簡單聊聊分布式鎖 Redis分布式鎖
單機redis分布式鎖 單機redis分布式鎖 首先咱們先聊聊單機的redis分布式鎖 第乙個最普通的實現方式,就是在 redis 裡使用 setnx 命令建立乙個 key,這樣就算加鎖。set resource name my random value nx px 30000執行這個命令就 ok。...
簡單聊聊分布式鎖 zookeeper分布式鎖
zookeeper分布式鎖 zookeeper分布式鎖 舉個栗子。對某乙個資料連續發出兩個修改操作,兩台機器同時收到了請求,但是只能一台機器先執行完另外乙個機器再執行。那麼此時就可以使用 zookeeper 分布式鎖,乙個機器接收到了請求之後先獲取 zookeeper 上的一把分布式鎖,就是可以去建...
分布式 分布式鎖
本質是利用redis的setnx 方法的特性來加鎖,setnx 即key不存在則設定key,否則直接返回false,要求在分布式系統中使用同乙個redis服務,以下提供兩種解決方案 1 直接使用redistemplate 這其實並不能完全保證高併發下的安全問題,因為可能在鎖過期之後該執行緒尚未執行完...