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 宕机, 那么只要当前正常的服务器超过集群的半数, 依然可以正常提供服务 持有锁资源服务器宕机, ...
随机推荐
- pow(x,y)函数的实现算法(递归函数)
函数pow(x,y)实现运算x^y,即x的y次方,这里x和y都为整数. 算法的基本思想是,减少乘法次数,重复利用结算结果,例如: x^4,如果逐个相乘的话,需要四次乘法.如果我们这样分解(x^2)*( ...
- dbrd 8.4.6 源代码编译安装
---------------------------- 0.系统环境 ---------------------------- db01 192.168.50.10 /dev/sdb1 主节点 db ...
- CentOS6.x和CentOS7.X启动系统不显示进度条设置方法
[root@ok Desktop]# vi /boot/grub/grub.conf # grub.conf generated by anaconda # # Note that you do no ...
- CentOS搭建Nginx+Subversion环境(包括多个版本库的配置)
Apache Subversion(简称SVN,svn) 因为某种原因我们需要用Nginx作为Subversion的http前端,但目前没有现成的Nginx+Subversion搭配方式. 而Subv ...
- 0064 MyBatis动态SQL--choose-when-otherwise--foreach--set--bind
读写数据库的时候,往往要根据传入的参数的不同,改变sql语句. 比如:如果传入了某个参数值,那就查询对应的字段,没传入,那就不查,这就是0048中的where--if 再比如: 如果传入了某个参数值, ...
- Python教程:[43]Word基本操作
使用python操作Word用到了win32com模块,我们现在就要介绍一下python对Word的基本操作,文章涉及到如何与Word程序建立连接.如果与Word文档建立连接的,以及对Word文档的基 ...
- oozie调度hive脚本demo
1. 环境配置 2. 脚本配置 3. 执行job 4. 查看结果 待发布 ..
- awk "sort -rnk3"
[root@Cobbler logs]# awk 'BEGIN{print "IP地址","访问流量","访问次数"}{a[$1]++;b[ ...
- 关于webRTC中video的使用实践
此次demo使用chrome49调试测试 前端在操作视频输入,音频输入,输出上一直是比较弱的,或者说很难进行相关的操作,经过我最近的一些研究发现,在PC上实际上是可以实现这一系列的功能的,其实现原理主 ...
- loadOnStartup = 1
在servlet的配置当中,<load-on-startup>5</load-on-startup>的含义是:标记容器是否在启动的时候就加载这个servlet.当值为0或者大于 ...