ZooKeeper 分布式鎖 Curator 源碼 05:分布式讀寫(xiě)鎖和聯(lián)鎖
前言
Curator 同樣支持分布式讀寫(xiě)鎖[1] 和聯(lián)鎖[2],只需要使用 InterProcessReadWriteLock 即可,來(lái)一起看看它的源碼以及實(shí)現(xiàn)方式。
1.使用方式
- public class CuratorDemo {
- public static void main(String[] args) throws Exception {
- String connectString = "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183";
- RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
- CuratorFramework client = CuratorFrameworkFactory
- .builder()
- .connectString(connectString)
- .retryPolicy(retryPolicy)
- .build();
- client.start();
- InterProcessReadWriteLock lock = new InterProcessReadWriteLock(client, "/locks/lock_01");
- lock.readLock().acquire();
- lock.readLock().release();
- lock.writeLock().acquire();
- lock.writeLock().release();
- }
- }
2.源碼
讀鎖寫(xiě)鎖都是基于 InterProcessMutex 實(shí)現(xiàn)的,所以基本都和 InterProcessMutex 沒(méi)有區(qū)別。不過(guò)這里生成的鎖名字不再是 -lock- 而是換成了 __WRIT__ 和 __READ__。
讀鎖加鎖節(jié)點(diǎn)名為 /locks/lock_01/_c_44a8eaf8-f177-403a-92bf-9119591b54d5-__READ__0000000000,寫(xiě)鎖解鎖節(jié)點(diǎn)名為 _c_2e5dde98-c548-4f8b-a798-821ee8330eb6-__WRIT__0000000001。
其中創(chuàng)建節(jié)點(diǎn)時(shí)和可重入鎖 InterProcessMutex 沒(méi)有區(qū)別,唯一的區(qū)別就是在 internalLockLoop 方法中,判斷鎖獲取結(jié)果時(shí)有區(qū)別。
當(dāng)可重入鎖時(shí)是在 StandardLockInternalsDriver#getsTheLock 判斷當(dāng)前節(jié)點(diǎn)是否為最小節(jié)點(diǎn)。
而讀寫(xiě)鎖是在 InterProcessReadWriteLock#InterProcessReadWriteLock 中重寫(xiě)了 getsTheLock 方法。
讀鎖加鎖
讀鎖加鎖,當(dāng)前線(xiàn)程直接返回成功,也就是說(shuō)當(dāng)前線(xiàn)程讀寫(xiě)不互斥的。
如果是其他線(xiàn)程,則遍歷所有子節(jié)點(diǎn)。
子節(jié)點(diǎn)包含寫(xiě)鎖,當(dāng)前節(jié)點(diǎn)在子節(jié)點(diǎn)有序集合的索引小于寫(xiě)鎖的索引則直接獲得鎖,否則獲取失敗;
子節(jié)點(diǎn)不包含寫(xiě)鎖,則當(dāng)前節(jié)點(diǎn)在子節(jié)點(diǎn)的有序集合的 index < Integer.MAX_VALUE (2147483647) 即可。
就是說(shuō)讀鎖最多支持 2147483647 個(gè)。
寫(xiě)鎖加鎖
寫(xiě)鎖加鎖直接復(fù)用的可重入鎖 InterProcessMutex 的邏輯,所以這里寫(xiě)鎖和寫(xiě)鎖,以及讀鎖和寫(xiě)鎖都是互斥的。
3.聯(lián)鎖
聯(lián)鎖的使用,就是將 InterProcessLock 放到集合中,然后進(jìn)行統(tǒng)一加鎖。
加鎖就遍歷集合,依次進(jìn)行加鎖。
4.總結(jié)
本文介紹了讀寫(xiě)鎖和聯(lián)鎖,其實(shí)都是基于最基礎(chǔ)的可重入鎖進(jìn)行封裝,理解了可重入鎖的概念,后面的簡(jiǎn)單看下思想即可。
引用鏈接:
[1]Shared Reentrant Read Write Lock: https://curator.apache.org/curator-recipes/shared-reentrant-read-write-lock.html
[2]Multi Shared Lock: https://curator.apache.org/curator-recipes/multi-shared-lock.html