最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Redisson分布式鎖實(shí)現(xiàn)

2022-10-14 12:03 作者:萬(wàn)事俱備就差個(gè)程序員  | 我要投稿

Redisson分布式鎖實(shí)現(xiàn)

  多線程下的數(shù)據(jù)一致性問(wèn)題一直都是熱點(diǎn)問(wèn)題,既要考慮到數(shù)據(jù)的一致,又要考慮實(shí)現(xiàn)的效率,在分布式情況下,這又要成為一種新的難題。分布式鎖和我們java基礎(chǔ)中學(xué)習(xí)到的synchronized略有不同,synchronized中我們的鎖是個(gè)對(duì)象,當(dāng)前系統(tǒng)部署在不同的服務(wù)實(shí)例上,單純使用synchronized或者lock 已經(jīng)無(wú)法滿足對(duì)庫(kù)存一致性的判斷。本次主要講解基于rediss 實(shí)現(xiàn)的分布式鎖、

基本用法

<dependency> ? ?<groupId>org.redisson</groupId> ? ?<artifactId>redisson</artifactId> ? ?<version>3.8.2</version> </dependency>Config config = new Config(); config.useClusterServers() ? ?.setScanInterval(2000) // cluster state scan interval in milliseconds ? ?.addNodeAddress("redis://127.0.0.1:7000", "redis://127.0.0.1:7001") ? ?.addNodeAddress("redis://127.0.0.1:7002");
RedissonClient redisson = Redisson.create(config);

1. 可重入鎖(Reentrant Lock)

Redisson的分布式可重入鎖RLock Java對(duì)象實(shí)現(xiàn)了java.util.concurrent.locks.Lock接口,同時(shí)還支持自動(dòng)過(guò)期解鎖。

public void testReentrantLock(RedissonClient redisson){ ? ? ? ?RLock lock = redisson.getLock("anyLock"); ? ? ? ?try{ ? ? ? ? ? ?// 1. 最常見(jiàn)的使用方法 ? ? ? ? ? ?//lock.lock(); ? ? ? ? ? ?// 2. 支持過(guò)期解鎖功能,10秒鐘以后自動(dòng)解鎖, 無(wú)需調(diào)用unlock方法手動(dòng)解鎖 ? ? ? ? ? ?//lock.lock(10, TimeUnit.SECONDS); ? ? ? ? ? ?// 3. 嘗試加鎖,最多等待3秒,上鎖以后10秒自動(dòng)解鎖 ? ? ? ? ? ?boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS); ? ? ? ? ? ?if(res){ ? ?//成功 ? ? ? ? ? ? ? ?// do your business ? ? ? ? ? ?} ? ? ? ?} catch (InterruptedException e) { ? ? ? ? ? ?e.printStackTrace(); ? ? ? ?} finally { ? ? ? ? ? ?lock.unlock(); ? ? ? ?} ? ?}

Redisson同時(shí)還為分布式鎖提供了異步執(zhí)行的相關(guān)方法:

public void testAsyncReentrantLock(RedissonClient redisson){ ? ? ? ?RLock lock = redisson.getLock("anyLock"); ? ? ? ?try{ ? ? ? ? ? ?lock.lockAsync(); ? ? ? ? ? ?lock.lockAsync(10, TimeUnit.SECONDS); ? ? ? ? ? ?Future<Boolean> res = lock.tryLockAsync(3, 10, TimeUnit.SECONDS); ? ? ? ? ? ?if(res.get()){ ? ? ? ? ? ? ? ?// do your business ? ? ? ? ? ?} ? ? ? ?} catch (InterruptedException e) { ? ? ? ? ? ?e.printStackTrace(); ? ? ? ?} catch (ExecutionException e) { ? ? ? ? ? ?e.printStackTrace(); ? ? ? ?} finally { ? ? ? ? ? ?lock.unlock(); ? ? ? ?} ? ?}

2. 公平鎖(Fair Lock)

Redisson分布式可重入公平鎖也是實(shí)現(xiàn)了java.util.concurrent.locks.Lock接口的一種RLock對(duì)象。在提供了自動(dòng)過(guò)期解鎖功能的同時(shí),保證了當(dāng)多個(gè)Redisson客戶端線程同時(shí)請(qǐng)求加鎖時(shí),優(yōu)先分配給先發(fā)出請(qǐng)求的線程。

public void testFairLock(RedissonClient redisson){ ? ? ? ?RLock fairLock = redisson.getFairLock("anyLock"); ? ? ? ?try{ ? ? ? ? ? ?// 最常見(jiàn)的使用方法 ? ? ? ? ? ?fairLock.lock(); ? ? ? ? ? ?// 支持過(guò)期解鎖功能, 10秒鐘以后自動(dòng)解鎖,無(wú)需調(diào)用unlock方法手動(dòng)解鎖 ? ? ? ? ? ?fairLock.lock(10, TimeUnit.SECONDS); ? ? ? ? ? ?// 嘗試加鎖,最多等待100秒,上鎖以后10秒自動(dòng)解鎖 ? ? ? ? ? ?boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS); ? ? ? ?} catch (InterruptedException e) { ? ? ? ? ? ?e.printStackTrace(); ? ? ? ?} finally { ? ? ? ? ? ?fairLock.unlock(); ? ? ? ?} ? ?}

Redisson同時(shí)還為分布式可重入公平鎖提供了異步執(zhí)行的相關(guān)方法:

RLock fairLock = redisson.getFairLock("anyLock"); fairLock.lockAsync(); fairLock.lockAsync(10, TimeUnit.SECONDS); Future<Boolean> res = fairLock.tryLockAsync(100, 10, TimeUnit.SECONDS);

3. 聯(lián)鎖(MultiLock)

Redisson的RedissonMultiLock對(duì)象可以將多個(gè)RLock對(duì)象關(guān)聯(lián)為一個(gè)聯(lián)鎖,每個(gè)RLock對(duì)象實(shí)例可以來(lái)自于不同的Redisson實(shí)例。

public void testMultiLock(RedissonClient redisson1, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?RedissonClient redisson2, RedissonClient redisson3){ ? ? ? ?RLock lock1 = redisson1.getLock("lock1"); ? ? ? ?RLock lock2 = redisson2.getLock("lock2"); ? ? ? ?RLock lock3 = redisson3.getLock("lock3"); ? ? ? ?RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3); ? ? ? ?try { ? ? ? ? ? ?// 同時(shí)加鎖:lock1 lock2 lock3, 所有的鎖都上鎖成功才算成功。 ? ? ? ? ? ?lock.lock(); ? ? ? ? ? ?// 嘗試加鎖,最多等待100秒,上鎖以后10秒自動(dòng)解鎖 ? ? ? ? ? ?boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); ? ? ? ?} catch (InterruptedException e) { ? ? ? ? ? ?e.printStackTrace(); ? ? ? ?} finally { ? ? ? ? ? ?lock.unlock(); ? ? ? ?} ? ?}

4. 紅鎖(RedLock)

Redisson的RedissonRedLock對(duì)象實(shí)現(xiàn)了Redlock介紹的加鎖算法。該對(duì)象也可以用來(lái)將多個(gè)RLock
對(duì)象關(guān)聯(lián)為一個(gè)紅鎖,每個(gè)RLock對(duì)象實(shí)例可以來(lái)自于不同的Redisson實(shí)例。

? ?public void testRedLock(RedissonClient redisson1, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?RedissonClient redisson2, RedissonClient redisson3){ ? ? ? ?RLock lock1 = redisson1.getLock("lock1"); ? ? ? ?RLock lock2 = redisson2.getLock("lock2"); ? ? ? ?RLock lock3 = redisson3.getLock("lock3"); ? ? ? ?RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3); ? ? ?try { ? ? ? ? ? ?// 同時(shí)加鎖:lock1 lock2 lock3, 紅鎖在大部分節(jié)點(diǎn)上加鎖成功就算成功。 ? ? ? ? ? ?lock.lock(); ? ? ? ? ? ?// 嘗試加鎖,最多等待100秒,上鎖以后10秒自動(dòng)解鎖 ? ? ? ? ? ?boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); ? ? ? ?} catch (InterruptedException e) { ? ? ? ? ? ?e.printStackTrace(); ? ? ? ?} finally { ? ? ? ? ? ?lock.unlock(); ? ? ? ?} ? ?}

5. 讀寫(xiě)鎖(ReadWriteLock)

Redisson的分布式可重入讀寫(xiě)鎖RReadWriteLock Java對(duì)象實(shí)現(xiàn)了java.util.concurrent.locks.ReadWriteLock接口。同時(shí)還支持自動(dòng)過(guò)期解鎖。該對(duì)象允許同時(shí)有多個(gè)讀取鎖,但是最多只能有一個(gè)寫(xiě)入鎖。

RReadWriteLock rwlock = redisson.getLock("anyRWLock");// 最常見(jiàn)的使用方法rwlock.readLock().lock();// 或rwlock.writeLock().lock();// 支持過(guò)期解鎖功能// 10秒鐘以后自動(dòng)解鎖// 無(wú)需調(diào)用unlock方法手動(dòng)解鎖rwlock.readLock().lock(10, TimeUnit.SECONDS);// 或rwlock.writeLock().lock(10, TimeUnit.SECONDS);// 嘗試加鎖,最多等待100秒,上鎖以后10秒自動(dòng)解鎖boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);// 或boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS); ...lock.unlock();

6. 信號(hào)量(Semaphore)

Redisson的分布式信號(hào)量(Semaphore)Java對(duì)象RSemaphore采用了與java.util.concurrent.Semaphore相似的接口和用法。

RSemaphore semaphore = redisson.getSemaphore("semaphore"); semaphore.acquire();//或semaphore.acquireAsync(); semaphore.acquire(23); semaphore.tryAcquire();//或semaphore.tryAcquireAsync(); semaphore.tryAcquire(23, TimeUnit.SECONDS);//或semaphore.tryAcquireAsync(23, TimeUnit.SECONDS); semaphore.release(10); semaphore.release();//或semaphore.releaseAsync();

7. 可過(guò)期性信號(hào)量(PermitExpirableSemaphore)

Redisson的可過(guò)期性信號(hào)量(PermitExpirableSemaphore)實(shí)在RSemaphore對(duì)象的基礎(chǔ)上,為每個(gè)信號(hào)增加了一個(gè)過(guò)期時(shí)間。每個(gè)信號(hào)可以通過(guò)獨(dú)立的ID來(lái)辨識(shí),釋放時(shí)只能通過(guò)提交這個(gè)ID才能釋放。

RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore("mySemaphore"); String permitId = semaphore.acquire();// 獲取一個(gè)信號(hào),有效期只有2秒鐘。String permitId = semaphore.acquire(2, TimeUnit.SECONDS);// ...semaphore.release(permitId);

8. 閉鎖(CountDownLatch)

Redisson的分布式閉鎖(CountDownLatch)Java對(duì)象RCountDownLatch采用了與java.util.concurrent.CountDownLatch相似的接口和用法。

RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch"); latch.trySetCount(1); latch.await();// 在其他線程或其他JVM里RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch"); latch.countDown();

?

加鎖有如下注意事項(xiàng):

  • 加鎖需要設(shè)置超時(shí)時(shí)間,防止出現(xiàn)死鎖

  • 加鎖以及設(shè)置超時(shí)時(shí)間的時(shí)候,需要保證兩個(gè)操作的原子性,因而最好使用lua腳本或者使用支持NX以及EX的set方法

  • 加鎖的時(shí)候需要把加鎖的調(diào)用方信息,比如線程id給記錄下來(lái),這個(gè)在解鎖的時(shí)候需要使用

  • 對(duì)于加鎖時(shí)長(zhǎng)不確定的任務(wù),為防止任務(wù)未執(zhí)行完導(dǎo)致超時(shí)被釋放,需要對(duì)尚未運(yùn)行完的任務(wù)延長(zhǎng)失效時(shí)間

解鎖有如下注意事項(xiàng):

  • 解鎖一系列操作(判斷key是否存在,存在的話刪除key等)需要保證原子性,因而最好使用lua腳本

  • 解鎖需要判斷調(diào)用方是否與加鎖時(shí)記錄的是否一致,防止鎖被誤刪

  • 如果有延續(xù)失效時(shí)間的延時(shí)任務(wù),在解鎖的時(shí)候,需要終止掉該任務(wù)


Redisson分布式鎖實(shí)現(xiàn)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
墨江| 塔城市| 华坪县| 柯坪县| 隆尧县| 钟山县| 平邑县| 伊宁县| 广德县| 郁南县| 舟山市| 顺平县| 绥化市| 龙胜| 宜章县| 青浦区| 辽宁省| 铁岭县| 新巴尔虎右旗| 太湖县| 尼勒克县| 阳城县| 哈巴河县| 沿河| 玉环县| 海林市| 仁怀市| 吴江市| 名山县| 河间市| 青海省| 河津市| 施甸县| 邯郸市| 古蔺县| 沧源| 思茅市| 大城县| 绵阳市| 缙云县| 津市市|