ZooKeeper 分布式锁 Curator 源码 04:分布式信号量和互斥锁
前言
分布式信号量,之前在 Redisson 中也介绍过,Redisson 的信号量是将计数维护在 Redis 中的,那现在来看一下 Curator 是如何基于 ZooKeeper 实现信号量的。
使用 Demo
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();
InterProcessSemaphoreV2 semaphore = new InterProcessSemaphoreV2(client, "/semaphores/semaphore_01", 3);
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread() + " 线程 start - " + LocalTime.now());
Lease lease = semaphore.acquire();
System.out.println(Thread.currentThread() + " 线程 execute - " + LocalTime.now());
Thread.sleep(3000);
System.out.println(Thread.currentThread() + " 线程 over -" + LocalTime.now());
semaphore.returnLease(lease);
} catch (Exception e) {
}
}).start();
}
Thread.sleep(1000000);
}
}
控制台输出数据如下:

源码
获取凭证
核心源码:InterProcessSemaphoreV2#internalAcquire1Lease
这里仅介绍大概逻辑,有兴趣的小伙伴可以自行阅读源码。

lock 是 InterProcessMutex,InterProcessSemaphoreV2 信号量,也是借助于最基础的加锁。

通过图也可以看出,使用 InterProcessSemaphoreV2 时,会先创建 /semaphores/semaphore_01 路径,并在路径下创建 locks 节点。也就是 /semaphores/semaphore_01/locks 路径下,有 10 个临时顺序节点。

紧接着会在 /semaphores/semaphore_01 路径下创建 leases 节点,所以创建锁的临时顺序节点之后,会紧接着在 /semaphores/semaphore_01/leases 下创建临时顺序节点。

对 /semaphores/semaphore_01/leases 节点进行监听,同时获取 /semaphores/semaphore_01/leases 下面的子节点数量。
- 如果子节点数量小于等于信号量计数,则直接结束循环;
- 如果大于,则会进入 wait 等待唤醒。
释放凭证

释放凭证就是调用 Lease 的 close 方法,删除节点,这样 /semaphores/semaphore_01/leases 上的监听器就会触发,然后其他线程获取凭证。
互斥锁
互斥锁 InterProcessSemaphoreMutex,不支持重入,其他的和可重入锁并没有什么区别。就是基于 InterProcessSemaphoreV2 实现的。

就是把计数的值 maxLeases 设置为了 1。
总结
信号量 InterProcessSemaphoreV2 其实是通过判断节点下的子节点数量来实现控制信号量,同时内部加锁是基于可重入锁 InterProcessMutex 实现的。
互斥锁 InterProcessSemaphoreMutex 则是将信号量的技术设置为 1 来实现互斥功能。
相关推荐
- ZooKeeper 分布式锁 Curator 源码 03:可重入锁并发加锁
- ZooKeeper 分布式锁 Curator 源码 02:可重入锁重复加锁和锁释放
- ZooKeeper 分布式锁 Curator 源码 01:可重入锁
ZooKeeper 分布式锁 Curator 源码 04:分布式信号量和互斥锁的更多相关文章
- ZooKeeper 分布式锁 Curator 源码 02:可重入锁重复加锁和锁释放
ZooKeeper 分布式锁 Curator 源码 02:可重入锁重复加锁和锁释放 前言 加锁逻辑已经介绍完毕,那当一个线程重复加锁是如何处理的呢? 锁重入 在上一小节中,可以看到加锁的过程,再回头看 ...
- ZooKeeper 分布式锁 Curator 源码 03:可重入锁并发加锁
前言 在了解了加锁和锁重入之后,最需要了解的还是在分布式场景下或者多线程并发加锁是如何处理的? 并发加锁 先来看结果,在多线程对 /locks/lock_01 加锁时,是在后面又创建了新的临时节点. ...
- ZooKeeper 分布式锁 Curator 源码 01:可重入锁
前言 一般工作中常用的分布式锁,就是基于 Redis 和 ZooKeeper,前面已经介绍完了 Redisson 锁相关的源码,下面一起看看基于 ZooKeeper 的锁.也就是 Curator 这个 ...
- 【TencentOS tiny】深度源码分析(6)——互斥锁
互斥锁 互斥锁又称互斥互斥锁,是一种特殊的信号量,它和信号量不同的是,它具有互斥锁所有权.递归访问以及优先级继承等特性,在操作系统中常用于对临界资源的独占式处理.在任意时刻互斥锁的状态只有两种,开锁或 ...
- Golang 读写锁RWMutex 互斥锁Mutex 源码详解
前言 Golang中有两种类型的锁,Mutex (互斥锁)和RWMutex(读写锁)对于这两种锁的使用这里就不多说了,本文主要侧重于从源码的角度分析这两种锁的具体实现. 引子问题 我一般喜欢带着问题去 ...
- Redisson源码解读-分布式锁
前言 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).Redisson有一样功能是可重入的分布式锁.本文来讨论一下这个功能的特点以及源 ...
- [源码解析] 分布式任务队列 Celery 之启动 Consumer
[源码解析] 分布式任务队列 Celery 之启动 Consumer 目录 [源码解析] 分布式任务队列 Celery 之启动 Consumer 0x00 摘要 0x01 综述 1.1 kombu.c ...
- [源码分析] 分布式任务队列 Celery 之 发送Task & AMQP
[源码分析] 分布式任务队列 Celery 之 发送Task & AMQP 目录 [源码分析] 分布式任务队列 Celery 之 发送Task & AMQP 0x00 摘要 0x01 ...
- [源码分析] 分布式任务队列 Celery 多线程模型 之 子进程
[源码分析] 分布式任务队列 Celery 多线程模型 之 子进程 目录 [源码分析] 分布式任务队列 Celery 多线程模型 之 子进程 0x00 摘要 0x01 前文回顾 1.1 基类作用 1. ...
随机推荐
- CodeGen处理Synergy方法目录
CodeGen处理Synergy方法目录 如果Synergy应用程序开发环境包括使用Synergy/DE xfServerPlus,则可以基于Synergy方法目录中包含的元数据生成代码.要启用此功能 ...
- JDBCTemplate基本使用
用了jdbc连接池之后,我们会发现连接对象的复用性更高了,程序整体运行的性能也更高了.但是我们在做JDBC操作的时候还是比较麻烦,要定义sql,执行sql,设置参数,处理结果. 特别是当我们要做查询操 ...
- Jmeter-逻辑控制器If Controller的实例运用
一.If Controller概述 Expression (must evaluate to true or false) :表达式(值必须是true或false),也就是说,在右边文本框中输入的条件 ...
- 06:JS(02)
对象 一切皆对象 数组(类似于python里面的列表) [] var l = [11,22,33,44,55] typeof l "object" var l1 = [11,'sd ...
- 密码学系列之:blowfish对称密钥分组算法
目录 简介 blowfish详解 密钥数组和S-box 密钥数组 S-box 生成最终的K数组 blowfish blowfish的应用 blowfish的缺点 简介 Blowfish是由Bruce ...
- Redis不是只有get set那么简单
我以前还没接触Redis的时候,听到大数据组的小伙伴在讨论Redis,觉得这东西好高端,要是哪天我们组也可以使用下Redis就好了,好长一段时间后,我们项目中终于引入了Redis这个技术,我用了几下, ...
- 想玩转JAVA高并发,这些概念你必须懂
高并发高并发 它是互联网分布式系统架构设计中必须考虑的因素之一,通常是指,保证系统能够同时并行化处理海量请求 同步和异步 同步:发送一个请求,等待返回,然后再发送下一个请求.提交请求 -> 等待 ...
- Java-IO流的继承结构
一 IO流的继承结构如下 二 字节流 1.InputStream(字节流读取数据),为抽象类,不可创建对象:其具体实现需要通过子类FileInputStream(读取文件数据).BufferedI ...
- npm i安装命令中的-g -D -S的区别
-g为全局安装 -D 对模块进行局部安装,模块写入到 devDependencies 对象 用于开发阶段,开发时用到的工具等 -S 局部安装,不同的是模块写入到 dependencies对象 用于生产 ...
- 理解vertical-align
vertical-align 支持的属性值及组成 inherit 线类baseline, top, middle, bottom 文本类text-top, text-bottom 上标下标类sub, ...