基于zk“临时顺序节点“的分布式锁
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat; import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch; /**
* Created by zzq on 2019/6/25.
*/
public class ZKLock implements Watcher {
private ZooKeeper zk;
//当前锁
private String currentLock;
//资源名称
private String lockName;
//锁根节点
private String ROOT_LOCK = "/root_lock";
//锁的各个资源根节点
private String tmpRootLock;
//由于zookeeper监听节点状态会立即返回,所以需要使用CountDownLatch(也可使用信号量等其他机制)
private CountDownLatch latch; public ZKLock(String zkAddress, String lockName) {
this.lockName = "" + System.nanoTime();
try {
zk = new ZooKeeper(zkAddress, 30000, this);
createZNode(ROOT_LOCK, CreateMode.PERSISTENT);
tmpRootLock = ROOT_LOCK + "/" + lockName;
createZNode(tmpRootLock, CreateMode.PERSISTENT);//****zk临时节点下不能创建临时顺序节点
} catch (IOException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} private void createZNode(String node, CreateMode mode) throws KeeperException, InterruptedException {
//获取根节点状态
Stat stat = zk.exists(node, false);
//如果根节点不存在,则创建根节点,根节点类型为永久节点
if (stat == null) {
zk.create(node, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, mode);
}
} public void lock() {
try {
//在根节点下创建临时顺序节点,返回值为创建的节点路径
currentLock = zk.create(tmpRootLock + "/" + lockName, new byte[0],
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
//获取根节点下的所有临时顺序节点,不设置监视器
List<String> children = zk.getChildren(tmpRootLock, false);
//对根节点下的所有临时顺序节点进行从小到大排序
children.sort(null);
//判断当前节点是否为最小节点,如果是则获取锁,若不是,则找到自己的前一个节点,监听其存在状态
int curIndex = children.indexOf(currentLock.substring(currentLock.lastIndexOf("/") + 1));
if (curIndex != 0) {
//获取当前节点前一个节点的路径
String prev = children.get(curIndex - 1);
//监听当前节点的前一个节点的状态,null则节点不存在
Stat stat = zk.exists(tmpRootLock + "/" + prev, true);
//此处再次判断该节点是否存在
if (stat != null) {
latch = new CountDownLatch(1);
//进入等待锁状态
latch.await();
latch = null;
}
}
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} //释放锁
public void unlock() {
try {
//删除创建的节点
zk.delete(currentLock, -1);
List<String> children = zk.getChildren(tmpRootLock, false);
if (children.size() == 0) {
zk.delete(tmpRootLock, -1);
//关闭zookeeper连接
zk.close();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
currentLock = null;
} @Override
public void process(WatchedEvent event) {
if (this.latch != null) {
latch.countDown();
}
} public static void main(String[] args) throws Exception {
for (int i = 0; i < 7; i++) {
// new Thread(new Runnable() {
// @Override
// public void run() {
// ZKLock lock = new ZKLock("10.10.210.123:2181", "lock");
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// lock.lock();
// }
// }).start();
}
ZKLock lock = new ZKLock("10.10.210.123:2181", "L1");
lock.lock(); ZKLock lock1 = new ZKLock("10.10.210.123:2181", "L2");
lock1.lock();
lock1.unlock(); lock.unlock();
String uu = "";
}
}
基于zk“临时顺序节点“的分布式锁的更多相关文章
- Zookeeper--0300--java操作Zookeeper,临时节点实现分布式锁原理
删除Zookeeper的java客户端有 : 1,Zookeeper官方提供的原生API, 2,zkClient,在原生api上进行扩展的开源java客户端 3, 一.Zookeeper原生API ...
- 【spring boot】【redis】spring boot基于redis的LUA脚本 实现分布式锁
spring boot基于redis的LUA脚本 实现分布式锁[都是基于redis单点下] 一.spring boot 1.5.X 基于redis 的 lua脚本实现分布式锁 1.pom.xml &l ...
- 【连载】redis库存操作,分布式锁的四种实现方式[四]--基于Redis lua脚本机制实现分布式锁
一.redis lua介绍 Redis 提供了非常丰富的指令集,但是用户依然不满足,希望可以自定义扩充若干指令来完成一些特定领域的问题.Redis 为这样的用户场景提供了 lua 脚本支持,用户可以向 ...
- 基于redis集群实现的分布式锁,可用于秒杀商品的库存数量管理,有測试代码(何志雄)
转载请标明出处. 在分布式系统中,常常会出现须要竞争同一资源的情况,本代码基于redis3.0.1+jedis2.7.1实现了分布式锁. redis集群的搭建,请见我的另外一篇文章:<>& ...
- 基于redis集群实现的分布式锁,可用于秒杀,定时器。
在分布式系统中,经常会出现需要竞争同一资源的情况,使用redis可以实现分布式锁. 前提:redis集群已经整合项目,并且可以直接注入JedisCluster使用: @Autowired privat ...
- java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购
此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...
- zookeeper(4)--zookeeper分布式锁原理
目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency).可用性( ...
- ZooKeeper的分布式锁实现
分布式锁一般有三种实现方式: 1. 数据库乐观锁: 2. 基于Redis的分布式锁: 3. 基于ZooKeeper的分布式锁. 本篇博客将介绍第三种方式,基于Zookeeper实现分布式锁.虽然网上已 ...
- zookeeper分布式锁原理
一.分布式锁介绍分布式锁主要用于在分布式环境中保护跨进程.跨主机.跨网络的共享资源实现互斥访问,以达到保证数据的一致性. 二.架构介绍在介绍使用Zookeeper实现分布式锁之前,首先看当前的系统架构 ...
随机推荐
- java String长度与varchar长度匹配理解(字符和字节长度理解)
java String长度与varchar长度匹配理解(字符和字节长度理解) string中的length()长度,返回的是char的数量,每个char可以存储世界上任何类型的文字和字符,一个char ...
- 不折移动web不腾--开启我的个人Mac之旅
背景,非常久非常久曾经(听过)Linux,瞎玩 Mac mini,而今Linux下开发技能半身不遂,处于放任状态.明明就知道随着时间流逝会越陌生的东西越不想去抓住最后的余温,不知道这算不算放弃,反正迟 ...
- raywenderlich.com的Swift编程风格指南
翻译自:https://github.com/raywenderlich/swift-style-guide 这个风格指南可能和你从其它地方看到的不同,我们的焦点主要集中在互联网和文章上的可读性.创建 ...
- String的'+'的性能及原理
逛了几个论坛. 不少人在讨论String的"+",StringBuilder与StringBuffer等一系列的问题.先不多说了了 现分类详述: 1.String的'+',底层运行 ...
- Android应用程序相关的文件文件夹具体解释
一.方法介绍: 每一个Android应用程序都能够通过Context来获取与应用程序相关的文件夹,这些文件夹的功能各异,每一个文件夹都有自己的特点.有时候可能会搞混淆,本文结合andr ...
- 【详细】【转】C#中理解委托和事件 事件的本质其实就是委托 RabbitMQ英汉互翼(一),RabbitMQ, RabbitMQ教程, RabbitMQ入门
[详细][转]C#中理解委托和事件 文章是很基础,但很实用,看了这篇文章,让我一下回到了2016年刚刚学委托的时候,故转之! 1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托 ...
- 重写description方法
//重写description方法 //description建议大家在实际开发中都要重写这种方法.然后将类中有意义的成员变量打印出来,这样很方便我们调试程序 -(NSString *)descrip ...
- Error:全局变量不明白(using namespace std 与全局变量的冲突)
在用递归写八皇后时,定义了一个全局变量count,结果出现故障例如以下:提示全局变量不明白. 最后发如今实现文件.cpp中.我使用了using namespace std; 解决方法: 1.使用co ...
- TGraphicControl和TCustomControl自绘过程的理论解释
TGraphicControl = class(TControl) // 这个类实在是简单,因为所有事情都已经委托给它的父Win控件了,只要管自己即可 private FCanvas: TCanvas ...
- (函数即服务)Faas的现状与未来
刚看到jolestar一位从法律转行程序员的前辈写了一篇Faas现状与未来的文章,里面很多观点都很有启发,或许正如他说的那样,由于Faas能较好的解决资源利用率和开发效率问题,2018年Faas将变得 ...