Curator 的 InterProcessMutex 是 Java 世界里最常用的分布式锁。这篇用真实的 Curator 5.7.1 做五件事:互斥是否成立、可重入怎么实现、获取超时是否留垃圾、读写锁的排队规则,以及持有者 JVM 被冻结(长 GC)后会发生什么。
最终 200 / 200,用时 1.8 s
底层配方和kazoo 的锁一样:临时顺序节点,每个排队者只监听前一个。
InterProcessMutex 同线程第二次 acquire 成功;/re 下的锁节点:[_c_a6d12c5d-8272-4a0b-ba51-4c2f213d89df-lock-0000000000](只有 1 个节点,本地计数) release 一次后 /re 下还有 1 个节点(还没释放完) release 第二次后 /re 下有 0 个节点 InterProcessSemaphoreMutex 同线程第二次 acquire(1 s) → false,等了 1.0 s(自己把自己锁住了) 多 release 一次 → IllegalMonitorStateException
B.acquire(1 s) → false,1.02 s 后返回;/to 下的节点数 = 1(B 超时后自己的排队节点已清理) 锁节点名:[_c_49f6f480-6e0e-453b-b5f3-424034a23248-lock-0000000000]
0.0s 5 个读者都已持有读锁(同时在内的最大数 5) 1.5s 写者拿到写锁(此时读者数 0) 2.1s 写者之后到达的读者拿到读锁(等了 1.5 s)
读写锁在同一个路径下用两种前缀的顺序节点来排队,所以先后顺序由序号决定。
持有者被冻结 3.2 s 后,另一个进程 Waiter 拿到了同一把锁(会话超时 3 s)
持有者解冻后的日志:
ACQUIRED
STATE LOST
STATE RECONNECTED
AFTER_SLEEP isOwnedByCurrentThread=true isAcquiredInThisProcess=true只有持有者的 JVM 被冻结,ZooKeeper 服务端正常运行,所以会话超时后别人合法地拿到了锁。冻结的 JVM 恢复后先发现 LOST,再 RECONNECTED,但业务线程不会被打断。