什么是分布式鎖?
分布式鎖是控制分布式系統(tǒng)之間同步訪問共享資源的一種方式。在分布式系統(tǒng)中,常常需要協(xié)調(diào)他們的動作。如果不同的系統(tǒng)或是同一個系統(tǒng)的不同主機之間共享了一個或一組資源,那么訪問這些資源的時候,往往需要互斥來防止彼此干擾來保證一致性,在這種情況下,便需要使用到分布式鎖。
在Java中,由于多種原因,鎖定對象通常比使用同步塊更靈活。首先,Lock API可以以不同的方法運行,而同步塊完全包含在一個方法中。
另外,如果線程被阻止,則無法訪問同步的塊。使用Lock,該線程將僅在可用時獲取鎖。這大大減少了線程等待的時間。另外,當線程正在等待時,可以調(diào)用一種方法來中斷線程,而當線程正在等待獲取同步塊時,這是不可能的。
分布式鎖定意味著你不僅需要考慮多個線程或進程,還需要考慮在不同計算機上運行的不同客戶端。這些單獨的服務(wù)器必須進行協(xié)調(diào),以確保它們中的任何一個在任何給定時間都在使用資源。
基Redis的分布式Java鎖定工具
Redisson框架是用于Java的基于Redis的內(nèi)存數(shù)據(jù)網(wǎng)格,可為需要執(zhí)行分布式鎖定的程序員提供多個對象。 下面,我們將討論每個選項及其之間的區(qū)別。
1.鎖
RLock接口在Java中實現(xiàn)java.util.concurrent.locks.Lock接口。 這是一個可重入鎖,這意味著線程可以多次鎖定資源。 一個計數(shù)器變量跟蹤鎖定請求被執(zhí)行了多少次。 一旦線程發(fā)出足夠的解鎖請求并且計數(shù)器達到0,資源便被釋放。
以下簡單代碼示例演示了如何在Redisson中創(chuàng)建和初始化Lock:
RLock lock = redisson.getLock("anyLock");
// Most familiar locking method
lock.lock();
try {
...
} finally {
lock.unlock();
}
如果獲取此鎖的Redisson實例崩潰,則該鎖可能會在此獲取狀態(tài)下永久掛起。 為了避免這種情況,Redisson維護了一個鎖“看門狗”,該“看門狗”會在持有該鎖的Redisson實例仍處于活動狀態(tài)時延長該鎖的過期時間。 默認情況下,此鎖定看門狗的超時為30秒。 可以通過Config.lockWatchdogTimeout設(shè)置更改此限制。
Redisson還允許你在獲取租約時指定leaseTime參數(shù)。 在指定的時間間隔后,鎖將自動釋放:
// Acquire lock and release it automatically after 10 seconds
// if unlock method hasn't been invoked
lock.lock(10, TimeUnit.SECONDS);
// Wait for 100 seconds and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {
...
} finally {
lock.unlock();
}
}
Redisson還為Lock對象提供了異步/響應(yīng)/ rxjava2接口:
RLock lock = redisson.getLock("anyLock");
lock.lockAsync();
...
// Reactive Stream (Spring Project Reactor implementation)
RLockReactive lock = redissonReactive.getLock("anyLock");
Mono<Void> res = lock.lock();
...
// Reactive Stream (RxJava2 implementation)
RLockReactive lock = redissonRx.getLock("anyLock");
Flowable<Void> res = lock.lock();
...
由于RLock實現(xiàn)了Lock接口,因此只有擁有鎖的線程才能解鎖資源。 否則,任何嘗試都會遇到IllegalMonitorStateException。
2. FairLock
與其表兄弟RLock一樣,RFairLock也實現(xiàn)了java.util.concurrent.locks.Lock接口。 通過使用FairLock,你可以保證線程將按照請求資源的順序來獲取資源(即``先進先出''隊列)。 在為隊列中的下一個線程解鎖資源之前,Redisson會給已死掉五秒鐘的線程重新啟動。
與RLocks一樣,創(chuàng)建和啟動FairLock是一個簡單的過程:
RLock lock = redisson.getFairLock("anyLock");
lock.lock();
try {
...
} catch {
lock.unlock();
}
3. RedLock
RedissonRedLock對象實現(xiàn)Redlock鎖定算法,以將分布式鎖與Redis一起使用:
RLock lock1 = redissonInstance1.getLock("lock1");
RLock lock2 = redissonInstance2.getLock("lock2");
RLock lock3 = redissonInstance3.getLock("lock3");
RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3);
lock.lock();
try {
...
} finally {
lock.unlock();
}
在Redlock算法中,我們在單獨的計算機或虛擬機上有許多獨立的Redis主節(jié)點。 該算法嘗試使用相同的鍵名和隨機值依次獲取這些實例中的每個實例的鎖。 僅當客戶端能夠比鎖有效的總時間更快地從大多數(shù)實例中獲取鎖時,才獲取鎖。
4.ReadWriteLock
Redisson的RReadWriteLock實現(xiàn)了java.util.concurrent.locks.ReadWriteLock接口。 在Java中,讀/寫鎖實際上是兩個鎖的組合:一個只讀鎖可以同時由多個線程擁有,而寫鎖只能一次由一個線程擁有。
創(chuàng)建和初始化RReadWriteLock的方法如下:
RReadWriteLock rwlock = redisson.getReadWriteLock("anyRWLock");
rwlock.readLock().lock();
try {
...
} finally {
rwlock.readLock().lock();
}
rwlock.writeLock().lock();
try {
...
} finally {
rwlock.writeLock().lock();
}
5.多重鎖
RedissonMultiLock對象能夠?qū)⒍鄠€單獨的RLock實例組合在一起并作為單個實體進行管理:
RLock lock1 = redissonInstance1.getLock("lock1");
RLock lock2 = redissonInstance2.getLock("lock2");
RLock lock3 = redissonInstance3.getLock("lock3");
RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
lock.lock();
try {
...
} finally {
lock.unlock();
}
正如我們在上面的示例中看到的那樣,每個RLock對象可能屬于不同的Redisson實例。 反過來,這可能會連接到其他Redis數(shù)據(jù)庫。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
當前名稱:Redis分布式Java鎖的應(yīng)用-創(chuàng)新互聯(lián)
文章地址:http://m.kartarina.com/article12/ccgdgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、定制網(wǎng)站、App設(shè)計、網(wǎng)頁設(shè)計公司、外貿(mào)建站、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)