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 宕机, 那么只要当前正常的服务器超过集群的半数, 依然可以正常提供服务 持有锁资源服务器宕机, ...
随机推荐
- 相似微信的ChattingUi
先看主页面布局 activity_imitate_weixin_main.xml <RelativeLayout xmlns:android="http://schemas.andro ...
- OGNL表达式的基本语法和用法
首先我们一起来看一下OGNL中的#.%和$符号. 关于OGNL各种用法总结参看:http://blog.163.com/seara520@126/blog/static/720693042010320 ...
- xadmin 问题总结
pip install django-import-export
- Jquery 事件执行两次
js(jquery)的on绑定点击事件执行两次的解决办法—不是事件绑定而是事件冒泡 阻止冒泡的方法并不止 return false 这一种,还有event.stopPropagation(),这两种方 ...
- java常用操作
1.properties文件中文转换 在cmd中进入到文件所在目录执行(其他操作请见命令帮助):native2ascii -reverse messages_zh_CN.properties b.t ...
- Python中import和from import
Python里面的import和from import都是用于导入一个模块,两者的区别是 如果你在使用某模块内函数时不想写模块名,那么就用from import方式导入,如果是用import方式就要写 ...
- 确定文件的位置--浏览文件夹对话框folderBrowserDialog
private void button1_Click(object sender, EventArgs e) { folderBrowserDialog1.ShowNewFolderButton = ...
- 二、thinkphp
## ThinkPHP 3.1.2 查询方式#讲师:赵桐正微博:http://weibo.com/zhaotongzheng 本节课大纲:一.普通查询方式 a.字符串 $arr=$m->wher ...
- html5shiv.js分析-读源码之javascript系列
xiaolingzi 发表于 2012-05-31 23:42:29 首先,我们先了解一下html5shiv.js是什么. html5shiv.js是一套实现让ie低版本等浏览器支持html5标签的解 ...
- jquery mobile小经验
现在网站上关于jquery mobile的demo和帖子可真少啊,我刚开始接触,遇到了一些问题,都找不到人请教. 这是我的个人经验总结,或多或少会对刚入门的童鞋有点帮助吧. 如果想一开始进入页面的时候 ...