基于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实现分布式锁之前,首先看当前的系统架构 ...
随机推荐
- Hadoop2.0之YARN
YARN(Yet Another Resource Negotiator)是Hadoop2.0集群中负责资源管理和调度以及监控运行在它上面的各种应用,是hadoop2.0中的核心,它类似于一个分布式操 ...
- 在Electron中通过ffi模块实现JavaScript调用C++动态库
目前在网上能搜到的JS调C++动态库的实现有两种,一种是通过开发Node.js addon模块的方式实现调用,这种对于我们已有的代码实现比较复杂,需要大量的开发,因此不适用:另一种是通过FFI模块,F ...
- HDOJ题目4417 Super Mario(划分树求区间比k小的个数+二分)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- Erlang下与其他程序和语言的通信机制(2)
前面聊了普通端口,今天聊下链入式驱动端口,以及NIFs. 链入式驱动端口 如上图所示,链入式驱动端口与Erlang虚拟机存在于同一个OS进程中. 在Erlang这边与普通端口类似,所有与链入式驱动端口 ...
- Asp.Net实现JS前台带箭头的流程图方法总结!(个人笔记,信息不全)
Asp.Net实现JS前台带箭头的流程图方法总结!(持续更新中) 一.返回前台json格式 json5 = "[{\"Id\":2259,\"Name\&quo ...
- SSD性能优化记录
在上一篇博文中,我设计了一个优化方法,方法从业务角度出发,将切图操作涉及到的性能路径剖析出来,分别进行优化,效果显著. 眼下的情况是:一张ArcGIS武汉市城市影像图.该操作由79小时缩短至当前的67 ...
- OpenCV2马拉松第25圈——直线拟合与RANSAC算法
计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g/article/details/28118095 收入囊中 最小二乘法(least ...
- 大话设计模式宏观总结——创建型&结构型&行为型
师傅验收项目的时候.问大话设计模式那三种类型的差别和联系是什么,顿时我傻了眼.由于除了知道这三种类型分别如何称呼以外.从来都没想过为什么这样划分?于是,我便回答:我没想过这个问题.若是从字面上来理解的 ...
- balsamiq mockups 注册
Name: helloWorld Key: eJzzzU/OLi0odswsqslIzcnJD88vykmpsUQCNc41hjV+7q5+AF74Ds8=
- [置顶]
Snow的追寻
题目描述 Snow终于得知母亲是谁,他现在要出发寻找母亲. 王国中的路由于某种特殊原因,成为了一棵有n个节点的根节点为1的树,但由于"Birds are everywhere.", ...