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“临时顺序节点“的分布式锁的更多相关文章

  1. Zookeeper--0300--java操作Zookeeper,临时节点实现分布式锁原理

    删除Zookeeper的java客户端有  : 1,Zookeeper官方提供的原生API, 2,zkClient,在原生api上进行扩展的开源java客户端 3, 一.Zookeeper原生API ...

  2. 【spring boot】【redis】spring boot基于redis的LUA脚本 实现分布式锁

    spring boot基于redis的LUA脚本 实现分布式锁[都是基于redis单点下] 一.spring boot 1.5.X 基于redis 的 lua脚本实现分布式锁 1.pom.xml &l ...

  3. 【连载】redis库存操作,分布式锁的四种实现方式[四]--基于Redis lua脚本机制实现分布式锁

    一.redis lua介绍 Redis 提供了非常丰富的指令集,但是用户依然不满足,希望可以自定义扩充若干指令来完成一些特定领域的问题.Redis 为这样的用户场景提供了 lua 脚本支持,用户可以向 ...

  4. 基于redis集群实现的分布式锁,可用于秒杀商品的库存数量管理,有測试代码(何志雄)

    转载请标明出处. 在分布式系统中,常常会出现须要竞争同一资源的情况,本代码基于redis3.0.1+jedis2.7.1实现了分布式锁. redis集群的搭建,请见我的另外一篇文章:<>& ...

  5. 基于redis集群实现的分布式锁,可用于秒杀,定时器。

    在分布式系统中,经常会出现需要竞争同一资源的情况,使用redis可以实现分布式锁. 前提:redis集群已经整合项目,并且可以直接注入JedisCluster使用: @Autowired privat ...

  6. java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购

    此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...

  7. zookeeper(4)--zookeeper分布式锁原理

    目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency).可用性( ...

  8. ZooKeeper的分布式锁实现

    分布式锁一般有三种实现方式: 1. 数据库乐观锁: 2. 基于Redis的分布式锁: 3. 基于ZooKeeper的分布式锁. 本篇博客将介绍第三种方式,基于Zookeeper实现分布式锁.虽然网上已 ...

  9. zookeeper分布式锁原理

    一.分布式锁介绍分布式锁主要用于在分布式环境中保护跨进程.跨主机.跨网络的共享资源实现互斥访问,以达到保证数据的一致性. 二.架构介绍在介绍使用Zookeeper实现分布式锁之前,首先看当前的系统架构 ...

随机推荐

  1. vijos - P1122出栈序列统计 (卡特兰数)

    P1122出栈序列统计 未递交 标签:NOIP普及组2003[显示标签] 描写叙述 栈是经常使用的一种数据结构,有n令元素在栈顶端一側等待进栈,栈顶端还有一側是出栈序列. 你已经知道栈的操作有两·种: ...

  2. iOS常用的宏定义总结

    字符串是否为空 1   #define kStringIsEmpty(str) ([str isKindOfClass:[NSNull class]] || str == nil || [str le ...

  3. Linux 下查找文件或文件夹

    有些在我看来比较实用的命令,在这里记一下,避免每次都搜索一轮. 1.查找文件和文件夹 $ find . -name "mongo*" 从当前路径开始,向子目录查找名字含有 &quo ...

  4. Codeforces Round #319 (Div. 1)C. Points on Plane 分块思想

                                                                              C. Points on Plane On a pl ...

  5. cached

    /proc/sys/vm/ 关于Linux cached内存简析 - CSDN博客 http://blog.csdn.net/fox_hacker/article/details/41351687 [ ...

  6. Android TP(三)【转】

    本文转载自:http://blog.csdn.net/bi511304183/article/details/9303259 平台信息:内核:linux2.6/linux3.0系统:android/a ...

  7. Python中操作myslq的方法

    实例1.取得MYSQL的版本 在windows环境下安装mysql模块用于python开发,请见我的另一篇文章: MySQL-python Windows下EXE安装文件下载 # -*- coding ...

  8. http协议的MP4文件播放问题的分析

    现在手上有两个链接 (1) http://202.108.16.173/cctv/video/8C/35/EB/E8/8C35EBE84E7B483C8741CF9A60154993/gphone/4 ...

  9. Spark 机器学习 ---Word2Vec

    package Spark_MLlib import org.apache.spark.ml.feature.Word2Vec import org.apache.spark.sql.SparkSes ...

  10. 浅谈IO优化

    三层结构 磁盘(存储).VM(卷管理)和文件系统.专有名词不好理解,打个比方说:磁盘就相当于一块待用的空地:LVM相当于空地上的围墙(把空地划分成多个部分):文件系统则相当于每块空地上建的楼房(决定了 ...