05.Curator分布式锁
1.可重入锁Shared Reentrant Lock
// 构造方法public InterProcessMutex(CuratorFramework client, String path)public InterProcessMutex(CuratorFramework client, String path, LockInternalsDriver driver)// 通过acquire获得锁,并提供超时机制:public void acquire() throws Exceptionpublic boolean acquire(long time, TimeUnit unit) throws Exception// 撤销锁public void makeRevocable(RevocationListener<InterProcessMutex> listener)public void makeRevocable(final RevocationListener<InterProcessMutex> listener, Executor executor)
public class FakeLimitedResource{private final AtomicBoolean inUse = new AtomicBoolean(false);// 模拟只能单线程操作的资源public void use() throws InterruptedException{if (!inUse.compareAndSet(false, true)){// 在正确使用锁的情况下,此异常不可能抛出throw new IllegalStateException("Needs to be used by one client at a time");}try{Thread.sleep((long) (3 * Math.random()));}finally{inUse.set(false);}}}
public class ExampleClientThatLocks{private final InterProcessMutex lock;private final FakeLimitedResource resource;private final String clientName;public ExampleClientThatLocks(CuratorFramework client, String lockPath, FakeLimitedResource resource, String clientName){this.resource = resource;this.clientName = clientName;lock = new InterProcessMutex(client, lockPath);}public void doWork(long time, TimeUnit unit) throws Exception{if (!lock.acquire(time, unit)){throw new IllegalStateException(clientName + " 不能得到互斥锁");}try{System.out.println(clientName + " 已获取到互斥锁");resource.use(); // 使用资源Thread.sleep(1000 * 1);}finally{System.out.println(clientName + " 释放互斥锁");lock.release(); // 总是在finally中释放}}}
public class InterProcessMutexExample{private static final int QTY = 5;private static final int REPETITIONS = QTY * 10;private static final String PATH = "/examples/locks";public static void main(String[] args) throws Exception{final FakeLimitedResource resource = new FakeLimitedResource();final List<CuratorFramework> clientList = new ArrayList<CuratorFramework>();for (int i = 0; i < QTY; i++){CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));client.start();clientList.add(client);}System.out.println("连接初始化完成!");ExecutorService service = Executors.newFixedThreadPool(QTY);for (int i = 0; i < QTY; ++i){final int index = i;Callable<Void> task = new Callable<Void>(){@Overridepublic Void call() throws Exception{try{final ExampleClientThatLocks example = new ExampleClientThatLocks(clientList.get(index), PATH, resource, "Client " + index);for (int j = 0; j < REPETITIONS; ++j){example.doWork(10, TimeUnit.SECONDS);}}catch (Throwable e){e.printStackTrace();}finally{CloseableUtils.closeQuietly(clientList.get(index));}return null;}};service.submit(task);}service.shutdown();service.awaitTermination(10, TimeUnit.MINUTES);System.out.println("OK!");}}
连接初始化完成!Client 4 已获取到互斥锁Client 4 释放互斥锁Client 3 已获取到互斥锁Client 3 释放互斥锁......Client 2 已获取到互斥锁Client 2 释放互斥锁OK!

2.不可重入锁Shared Lock
public void doWork(long time, TimeUnit unit) throws Exception{if (!lock.acquire(time, unit)){throw new IllegalStateException(clientName + " 不能得到互斥锁");}System.out.println(clientName + " 已获取到互斥锁");if (!lock.acquire(time, unit)){throw new IllegalStateException(clientName + " 不能得到互斥锁");}System.out.println(clientName + " 再次获取到互斥锁");try{resource.use(); // 使用资源Thread.sleep(1000 * 1);}finally{System.out.println(clientName + " 释放互斥锁");lock.release(); // 总是在finally中释放lock.release(); // 获取锁几次 释放锁也要几次}}
3.可重入读写锁Shared Reentrant Read Write Lock

public class ExampleClientReadWriteLocks{private final InterProcessReadWriteLock lock;private final InterProcessMutex readLock;private final InterProcessMutex writeLock;private final FakeLimitedResource resource;private final String clientName;public ExampleClientReadWriteLocks(CuratorFramework client, String lockPath, FakeLimitedResource resource, String clientName){this.resource = resource;this.clientName = clientName;lock = new InterProcessReadWriteLock(client, lockPath);readLock = lock.readLock();writeLock = lock.writeLock();}public void doWork(long time, TimeUnit unit) throws Exception{// 注意只能先得到写锁再得到读锁,不能反过来!!!if (!writeLock.acquire(time, unit)){throw new IllegalStateException(clientName + " 不能得到写锁");}System.out.println(clientName + " 已得到写锁");if (!readLock.acquire(time, unit)){throw new IllegalStateException(clientName + " 不能得到读锁");}System.out.println(clientName + " 已得到读锁");try{resource.use(); // 使用资源Thread.sleep(1000 * 1);}finally{System.out.println(clientName + " 释放读写锁");readLock.release();writeLock.release();}}}
连接初始化完成!Client 1 已得到写锁Client 1 已得到读锁Client 1 释放读写锁......Client 3 已得到写锁Client 3 已得到读锁Client 3 释放读写锁OK!

4.信号量Shared Semaphore
- InterProcessSemaphoreV2 - 信号量实现类
- Lease - 租约(单个信号)
- SharedCountReader - 计数器,用于计算最大租约数量
public void returnLease(Lease lease)public void returnAll(Collection<Lease> leases)
public Lease acquire() throws Exceptionpublic Collection<Lease> acquire(int qty) throws Exceptionpublic Lease acquire(long time, TimeUnit unit) throws Exceptionpublic Collection<Lease> acquire(int qty, long time, TimeUnit unit) throws Exception
public class InterProcessSemaphoreExample{private static final int MAX_LEASE = 10;private static final String PATH = "/examples/locks";public static void main(String[] args) throws Exception{FakeLimitedResource resource = new FakeLimitedResource();CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));client.start();InterProcessSemaphoreV2 semaphore = new InterProcessSemaphoreV2(client, PATH, MAX_LEASE);Collection<Lease> leases = semaphore.acquire(5);System.out.println("获取租约数量:" + leases.size());Lease lease = semaphore.acquire();System.out.println("获取单个租约");resource.use();Collection<Lease> leases2 = semaphore.acquire(5, 10, TimeUnit.SECONDS);System.out.println("获取租约,如果为空则超时: " + leases2);System.out.println("释放租约");semaphore.returnLease(lease);System.out.println("释放集合中的所有租约");semaphore.returnAll(leases);client.close();System.out.println("OK!");}}
获取租约数量:5获取单个租约获取租约,如果为空则超时: null释放租约释放集合中的所有租约OK!

5.多锁对象 Multi Shared Lock
- InterProcessMultiLock - 对所对象实现类
- InterProcessLock - 分布式锁接口类
public InterProcessMultiLock(CuratorFramework client, List<String> paths)public InterProcessMultiLock(List<InterProcessLock> locks)
public class InterProcessMultiLockExample{private static final String PATH1 = "/examples/locks1";private static final String PATH2 = "/examples/locks2";public static void main(String[] args) throws Exception{FakeLimitedResource resource = new FakeLimitedResource();CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));client.start();InterProcessLock lock1 = new InterProcessMutex(client, PATH1); // 可重入锁InterProcessLock lock2 = new InterProcessSemaphoreMutex(client, PATH2); // 不可重入锁InterProcessMultiLock lock = new InterProcessMultiLock(Arrays.asList(lock1, lock2));if (!lock.acquire(10, TimeUnit.SECONDS)){throw new IllegalStateException("不能获取多锁");}System.out.println("已获取多锁");System.out.println("是否有第一个锁: " + lock1.isAcquiredInThisProcess());System.out.println("是否有第二个锁: " + lock2.isAcquiredInThisProcess());try{resource.use(); // 资源操作}finally{System.out.println("释放多个锁");lock.release(); // 释放多锁}System.out.println("是否有第一个锁: " + lock1.isAcquiredInThisProcess());System.out.println("是否有第二个锁: " + lock2.isAcquiredInThisProcess());client.close();System.out.println("OK!");}}
已获取多锁是否有第一个锁: true是否有第二个锁: true释放多个锁是否有第一个锁: false是否有第二个锁: falseOK!

-------------------------------------------------------------------------------------------------------------------------------
05.Curator分布式锁的更多相关文章
- curator 分布式锁InterProcessMutex
写这篇文章的目的主要是为了记录下自己在zookeeper 锁上踩过的坑,以及踩坑之后自己的一点认识; 从zk分布式锁原理说起,原理很简单,大家也应该都知道,简单的说就是zookeeper实现分布式锁是 ...
- Zookeeper+Curator 分布式锁
本来想着基于zk临时节点,实现一下分布式锁,结果发现有curator框架.PS:原声API真的难用,连递归创建path都没有? 配置curator maven的时候,md配置了好几个小时,最后发现集中 ...
- zookeeper 笔记--curator分布式锁
使用ZK实现分布式独占锁, 原理就是利用ZK同级节点的唯一性. Curator框架下的一些分布式锁工具InterProcessMutex:分布式可重入排它锁 InterProcessSemaphore ...
- 女朋友也能看懂的Zookeeper分布式锁原理
前言 关于分布式锁,在互联网行业的使用场景还是比较多的,比如电商的库存扣减,秒杀活动,集群定时任务执行等需要进程互斥的场景.而实现分布式锁的手段也很多,大家比较常见的就是redis跟zookeep ...
- SpringBoot电商项目实战 — Zookeeper的分布式锁实现
上一篇演示了基于Redis的Redisson分布式锁实现,那今天我要再来说说基于Zookeeper的分布式现实. Zookeeper分布式锁实现 要用Zookeeper实现分布式锁,我就不得不说说zo ...
- 【分布式锁】06-Zookeeper实现分布式锁:可重入锁源码分析
前言 前面已经讲解了Redis的客户端Redission是怎么实现分布式锁的,大多都深入到源码级别. 在分布式系统中,常见的分布式锁实现方案还有Zookeeper,接下来会深入研究Zookeeper是 ...
- Curator Zookeeper分布式锁
Curator Zookeeper分布式锁 pom.xml中添加如下配置 <!-- https://mvnrepository.com/artifact/org.apache.curator/c ...
- zookeeper之分布式锁以及分布式计数器(通过curator框架实现)
有人可能会问zookeeper我知道,但是curator是什么呢? 其实curator是apachede针对zookeeper开发的一个api框架是apache的顶级项目 他与zookeeper原生a ...
- Curator实现分布式锁
分布式锁的应用 分布式锁服务宕机, ZooKeeper 一般是以集群部署, 如果出现 ZooKeeper 宕机, 那么只要当前正常的服务器超过集群的半数, 依然可以正常提供服务 持有锁资源服务器宕机, ...
随机推荐
- [svc]influxdb+grafana实战-各省份api访问成功率统计
简单说下需求: 统计各个省份的 3大运营商的接口访问成功率,绘图展示 数据格式 {"mobile" : "15812345608", "provinc ...
- windows 和 linux 安装 scrapyd 出现Not a directory site-packages/scrapyd-1.0.1-py2.7.egg/scrapyd/txapp.py
1 这是因为 scrapyd安装的时候没有 解压 对应的 egg而导致的文件找不到的错误. 2 解决的方法,找到 scrapyd-1.0.1-py2.7.egg 解压缩 里面 有一个 scrapy ...
- 【计算机网络】IP分类
A类IP地址 A类IP地址:用可变的7位(bit)来标识网络号,可变的24位标识主机号,最前面一位为"0",即A类地址的第一段取值介于1-126之间.A类地址通常为大型网络而提供, ...
- 【ActiveMQ】ActiveMQ在Windows的安装,以及点对点的消息发送案例
公司最近会用MQ对某些业务进行处理,所以,这次我下载了apache-activemq-5.12.0-bin把玩下. 基于练习方便需要,使用Windows的版本. 参考的优秀文章: activemq的几 ...
- V模型与测试级别
V模型与测试级别[1] 2015-06-24 目录 2.1.1 V模型2.2.1 单元测试2.2.2 集成测试2.2.3 系统测试2.2.4 验收测试 2.1.1 V模型 返回 单元测试:验证软件单元 ...
- Java Mail(三):Session、Message详解
http://blog.csdn.net/ghsau/article/details/17909093 ************************************* 本文来自:高爽|Co ...
- FreeRTOS——1
以下转载自安富莱电子: http://forum.armfly.com/forum.php FreeRTOS 的特点 FreeRTOS 的主要特点如下:1. 支持抢占式调度,合作式调度和时间片调度.2 ...
- 匈牙利命名法、骆驼命名法、帕斯卡(pascal)命名法 C#命名规范
匈牙利命名法.骆驼命名法.帕斯卡(pascal)命名法 C#命名规范 一.匈牙利命名法:广泛应用于象Microsoft Windows这样的环境中. Windows 编程中用到的变量(还包括宏)的命名 ...
- LinkQ 组合查询与分页
1.以开头查 public List<Car> Select1(string a){ return con.Car.Where(r => r.Name.StartsWith(a)). ...
- hadoop之mapreduce编程实例(系统日志初步清洗过滤处理)
刚刚开始接触hadoop的时候,总觉得必须要先安装hadoop集群才能开始学习MR编程,其实并不用这样,当然如果你有条件有机器那最好是自己安装配置一个hadoop集群,这样你会更容易理解其工作原理.我 ...