ZooKeeper连接并创建节点以及实现分布式锁操作节点排序输出最小节点Demo
class LockThread implements Runnable {
private DistributedLock lock; public LockThread(int threadId,CountDownLatch latch) throws Exception {
this.lock = new DistributedLock(threadId,latch);
} @Override
public void run() {
//每一个线程对象启动后都应该创建一个临时的节点信息
try {
this.lock.handle();//进行具体的操作处理
} catch (Exception e) {
e.printStackTrace();
}
}
} public class TestDistributedLock { public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
new Thread(new LockThread(i,latch)).start();;
}
//Thread.sleep(Long.MAX_VALUE);//为了保证可以观察到所有的临时节点信息,保证此处先不进行关闭
latch.await();
System.out.println("************* 所有的线程对象操作完毕 *************");
}
public class DistributedLock {//建立一个描述分布式锁的程序处理类
public static final String CONNECTION_RUL = "192.168.12.121:2181,192.168.12.122:2181"; public static final int SESSION_TIMEOUT = 2000;//设置连接超时时间 public static final String AUTH_INFO = "zkuser:mldnjava";//进行连接的授权信息 public static final String GROUPNODE = "/mldn-lock";//根节点 public static final String SUNBODE = GROUPNODE + "/lockthread-";//子节点 private CountDownLatch latch = null; //本操作的主要目的是为了在取得zookeeper连接之后才能进行后续的处理
private CountDownLatch connectLatch = new CountDownLatch(1); private ZooKeeper zkClient = null; //建立Zookeeper程序控制类 private String selfPath; //保存每次创建的临时节点信息 private String waitPath; //保存下一个要进行处理的节点 private int threadId = 0; /** 进行一些初始化操作使用
*
* @param threadId 随意给定一个编号信息 * @param latch 进行线程同步处理
* @throws Exception */
public DistributedLock(int threadId, CountDownLatch latch) throws Exception {
this.threadId = threadId;//保存每一个线程对象自己的ID信息
this.latch = latch;
this.connectionZookeeper();//进行节点的连接
} public void handle() throws Exception {//具体业务处理
this.createSubNode();//创建临时节点操作
} public void handleSuccess() throws Exception {//表示取得锁之后进行的处理
if (this.zkClient.exists(this.selfPath, false) == null) {
return;//如果当前节点不存在
}
this.handleCallback();//执行具体的业务操作
//如果某一个节点操作完毕了,那么应该立即删除掉该节点,否则获得的最小节点永远都是该节点
this.zkClient.delete(selfPath, -1);
this.releaseZookeeper();//释放连接
this.latch.countDown();//进行减减的操作
} public void handleCallback() throws Exception {//取得分布式锁之后的目的是要进行具体的操作
Thread.sleep(200);//实现一个延迟处理
System.out
.println("****** Thread-" + this.threadId + "获得操作权,进行具体的业务操作");
} public boolean checkMinPath() throws Exception {//进行最小节点的判断
List<String> childen = this.zkClient.getChildren(GROUPNODE, false);//取得所有的节点信息
Collections.sort(childen); //进行所有节点的排序,这样最小的节点就拍到最上面
int index = childen
.indexOf(this.selfPath.substring(GROUPNODE.length() + 1));
switch (index) {
case 0: {
return true; //已经确定好当前的节点为最小节点
}
case -1: {
return false; //该节点可能已经消失了
}
default: {//表示该节点不属于最小节点,那么应该向后继续排查
this.waitPath = GROUPNODE + "/" + childen.get(index - 1);//获得下一个节点
try {
this.zkClient.getData(waitPath, true, new Stat());//取得下一个节点的数据
return false; //本节点不是当前的操作的最小节点
} catch (Exception e) {//如果出现了异常,则表示该节点不存在
if (this.zkClient.exists(waitPath, false) == null) {
return this.checkMinPath();//继续向后检测
} else {
throw e;
}
}
}
}
} public void createSubNode() throws Exception {//每一个线程对象的启动都要求创建一个节点信息
this.zkClient.create(SUNBODE, ("Thread-" + this.threadId).getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("【Thread-" + this.threadId + "、创建新的临时节点】"
+ this.selfPath);
//当节点创建完成之后就需要进行最小节点的检测
if (this.checkMinPath()) {//如果当前的节点为整个项目的最小节点
this.handleSuccess();//进行锁后的具体操作
}
} public void connectionZookeeper() throws Exception {//连接zookeeper服务
this.zkClient = new ZooKeeper(CONNECTION_RUL, SESSION_TIMEOUT,
new Watcher() { @Override
public void process(WatchedEvent event) {
if (event.getType() == EventType.None) {//第一次连接zookeeper的时候会出现none
DistributedLock.this.connectLatch.countDown();//表示已经连接成功
} else { //要处理删除节点操作,并且要确定下一个节点是已经准备出来的节点信息
if (event.getType() == EventType.NodeDeleted
&& event.getPath().equals(
DistributedLock.this.waitPath)) {
try {
if (DistributedLock.this.checkMinPath()) {//如果当前的节点为整个项目的最小节点
DistributedLock.this.handleSuccess();//进行锁后的具体操作
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
});
this.zkClient.addAuthInfo("digest", AUTH_INFO.getBytes());//进行授权认证
if (this.zkClient.exists(GROUPNODE, false) == null) {
this.zkClient.create(GROUPNODE, "LOCKDEMO".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
this.connectLatch.await();//等待连接后才执行后续的功能
} public void releaseZookeeper() {//进行zookeeper的连接释放
if (this.zkClient != null) {
try {
this.zkClient.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ZooKeeper连接并创建节点以及实现分布式锁操作节点排序输出最小节点Demo的更多相关文章
- zookeeper应用:屏障、队列、分布式锁
zookeeper工具类: 获取连接实例:创建节点:获取子节点:设置节点数据:获取节点数据:访问控制等. package org.windwant.zookeeper; import org.apac ...
- ZooKeeper实践方案:(7) 分布式锁
1.基本介绍 分布式锁是控制分布式系统之间同步訪问共享资源的一种方式,须要相互排斥来防止彼此干扰来保证一致性. 利用Zookeeper的强一致性能够完毕锁服务.Zookeeper的官方文档是列举了两种 ...
- zookeeper 实现分布式锁zookeeper 使用 Curator 示例监听、分布式锁
下载地址: http://download.csdn.net/download/ttyyadd/10239642
- 在非SQL客户端使用命令行方式定期连接SQL Server 服务器并模拟用户查询操作,同时输出信息内容
一个很长的标题,实现的功能就是尽量使用非人力的方式模拟人去做一件事情,为了便于记录,将他们输出成文件方便查阅. 图形界面方式,使用微软自己的ConnMaker.exe,或者Microsoft 数据连接 ...
- 整理分布式锁:业务场景&分布式锁家族&实现原理
1.引入业务场景 业务场景一出现: 因为小T刚接手项目,正在吭哧吭哧对熟悉着代码.部署架构.在看代码过程中发现,下单这块代码可能会出现问题,这可是分布式部署的,如果多个用户同时购买同一个商品,就可能导 ...
- zookeeper分布式锁实现
1.定义分布式锁接口 package com.ljq.lock; import java.util.concurrent.TimeUnit; public interface DistributedL ...
- 分布式锁2 Java非常用技术方案探讨之ZooKeeper
前言: 由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.以自己结合实际工作中的一些经验和网上看到的一些资料 ...
- 跟着大神学zookeeper分布式锁实现-----来自Ruthless
前几天分享了@Ruthless大神的Redis锁,发现和大家都学习了很多东西.因为分布式锁里面,最好的实现是zookeeper的分布式锁.所以在这里把实现方式和大家分享一下. zookeeper分布式 ...
- zookeeper分布式锁
摘要:分享牛原创,zookeeper使用,zookeeper锁在实际项目开发中还是很常用的,在这里我们介绍一下zookeeper分布式锁的使用,以及我们如何zookeeper分布式锁的原理.zooke ...
随机推荐
- Asp.Net Core微服务再体验
ASP.Net Core的基本配置 .在VS中调试的时候有很多修改Web应用运行端口的方法.但是在开发.调试微服务应用的时候可能需要同时在不同端口上开启多个服务器的实例,因此下面主要看看如何通过命令行 ...
- jquery快速入门(三)
捕获内容和属性 1.DOM 操作 获得内容 - text().html() 以及 val() text() - 设置或返回所选元素的文本内容,如果不带值则是返回值,如果带值则是修改值,如:$('p') ...
- Cookie浅析
Cookie 翻阅了好久关于Cookie的博客及文档,感觉一直有一块结没有解开,所以一直难以在脑中形成一个顺畅的知识脉络.最后实在是遭不住,拉上我的大神朋友在食堂里坐了3个小时,问了个底朝天!总算形 ...
- 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU开发那些事 - 索引
大家好,我是痞子衡,是正经搞技术的痞子.本系列痞子衡给大家介绍的是飞思卡尔i.MX RT系列微控制器相关知识. 飞思卡尔半导体(现恩智浦半导体)于2017年开始推出的i.MX RT系列开启了高性能MC ...
- javascript小记一则:今天在写VS2005——.NET程序时,写的一个JS图片示例案例
源码如下,如遇调试问题,可以找我解决: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &quo ...
- Hibernate框架笔记02_主键生成策略_一级缓存_事务管理
目录 0. 结构图 1. 持久化类的编写规则 1.1 持久化和持久化类 1.2 持久化类的编写规则 2. 主键生成策略 2.1 主键的分类 2.2 主键生成策略 3. 持久化类的三种状态[了解] 3. ...
- MySQL分组查询与连接查询
一,分组查询 使用ORDER BY子句将表中的数据分成若干组(还是按行显示) 语法: SELECT 字段名[,聚集函数] FROM 表名 [WHERE子句] GROUP BY 要分组的字段名 [ORD ...
- JS添加或删除HTML dom元素的方法实例分析
本文实例讲述了JS代码添加或删除HTML dom元素的方法.分享给大家供大家参考,具体如下: 创建新的 HTML 元素 如需向 HTML DOM 添加新元素,您必须首先创建该元素(元素节点),然后向一 ...
- js 3D旋转效果
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- js函数式编程术语总结 - 持续更新
参考文档1 参考文档2 函数式编程术语 高阶函数 Higher-Order Functions 以函数为参数的函数 返回一个函数的函数 函数的元 Arity 比如,一个带有两个参数的函数被称为二元函数 ...