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 Exception
public 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>()
{
@Override
public 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 Exception
public Collection<Lease> acquire(int qty) throws Exception
public Lease acquire(long time, TimeUnit unit) throws Exception
public 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
是否有第二个锁: false
OK!

-------------------------------------------------------------------------------------------------------------------------------
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 宕机, 那么只要当前正常的服务器超过集群的半数, 依然可以正常提供服务 持有锁资源服务器宕机, ...
随机推荐
- 为什么会找不到D层文件?
近期两天在重装系统,今天好不easy把各种东西都装齐全了,再打开我的机房收费系统,就提演示样例如以下错误: 看到这个问题.我感觉非常熟,由于曾经也遇到过两次这个问题,都是改了下D层的编译路径.改到了U ...
- [svc]执行sudo时报错:effective uid is not 0
http://jingyan.baidu.com/article/c45ad29cd83d4b051753e232.html 今天将 / 授权给了一个普通用户 导致一些问题. 启事: 操作前一定要先在 ...
- angular学习疑问总结
服务里返回的数据是不是只能传给控制器,而不能传给指令呢?如果是的话那么指令只能通过配置scope属性来访问控制器里的数据
- libjpeg.a exists or that its path is correct
Android NDK: ERROR:/cygdrive/e/cocos2d-x/code/cocos2d-2.1rc0-x-2.1.3/HelloTest1/proj.android/../../c ...
- Eclipse上Hadoop插件中Run On Hadoop原理[转]
通过Eclipse的hadoop插件中的"run on hadoop"命令的原理:它不是把jar包发送到hadoop集群上去运行,而只是使用了hadoop集群上的hdfs,从hdf ...
- 什么是:before和:after?
前几天的晚上较全面的去看了下css的一些文档和资料,大部分的样式运用都没什么大问题了,只是有些许较陌生,但是也知道他们的存在和实现的是什么样式.今天主要想在这篇学习笔记中写的也不多,主要是针对:bef ...
- 浅谈HTTP中Get与Post的区别_转
可参考:HTTP请求中POST与GET的区别 Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个UR ...
- 如何让每个 WordPress 页面有不同的风格或者样式
如果使用 page.php 来处理所有页面的外观的话,答案肯定是不行的,但是如果使用不同的 WordPress 页面模板,就可以自定义每个页面的外观了. 比如你博客的所有的页面除了“关于”这个页面之外 ...
- Lua中的常用语句结构以及函数
1.Lua中的常用语句结构介绍 --if 语句结构,如下实例: gTable = {} ] ] then ]) == gTable[] then ]) else print("unkown ...
- Trie树 + DFS - CSU 1457 Boggle
Boggle Problem's Link: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1457 Mean: 给定n个串,有m个询问. 每个询问 ...