既上篇文章后,先介绍一下分布式锁后再聊zookeeper;
什么是分布式锁?

分布式锁有什么特点?
1)排他性:只有一个线程能获取到
2)阻塞性:其他未抢到的线程阻塞,直到锁释放出来,再抢。
3)可重入性:线程获得锁后,后续是否可重复获取该锁。
那么可不可以用zookeeper来做分布式锁呢?
zookeeper可以通过JDK栅栏来实现锁的阻塞性,通过计数器来实现锁的可重入性;
接下里我们看一下怎么在加锁之前,使用zookeeper开发呢???
创建客户端的核心类: Zookeeper(org.apache.zookeeper.Zookeeper方法就不一一列举了,源码上都有)缺点:在连接zk超时时不支持自动重连,watch注册一次会失效,需要反复注册,不支持递归创建节点,需要手动序列化;因此我们使用第三方客户端Zkclient进行开发

附上源码:
public class ZkClientDemo {
public static void main(String[] args) {
// 创建一个zk客户端
ZkClient client =new ZkClient("localhost:2181");
//设置序列化
client.setZkSerializer(new MyZkSerializer());
//创建节点
client.create("/test/zkdemo", "123", CreateMode.PERSISTENT);
//订阅一个watch
client.subscribeChildChanges("/test/zkdemo", new IZkChildListener() {
@Override
public void handleChildChange(String parentPath, List currentChilds)throws Exception {
//对子节点的监控
System.out.println(parentPath+"子节点发生变化:"+currentChilds);
}
});
client.subscribeDataChanges("/test/zkdemo", new IZkDataListener() {
@Override
public void handleDataDeleted(String dataPath)throws Exception {
System.out.println(dataPath+"节点被删除");
}
@Override
public void handleDataChange(String dataPath, Object data)throws Exception {
System.out.println(dataPath+"发生变化:"+data);
}
});
try {
Thread.currentThread().join();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyZkSerializerimplements ZkSerializer {
@Override
public byte[]serialize(Object data)throws ZkMarshallingError {
String d = (String) data;
try {
return d.getBytes("UTF-8");
}catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
@Override
public Objectdeserialize(byte[] bytes)throws ZkMarshallingError {
try {
return new String(bytes, "UTF-8");
}catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}
我们在本地新建 /test/zkdemo设值为1234345就会发现watch代码就会感知到如下图:

除了Zkclient 第三方客户端,还有Curator,功能更加丰富,主要都是为了解决Watch注册一次就会失效的问题,提供简单的api;
介绍到这儿入门差不多就这么多了,简单易懂,有疑问的可以一起来讨论~~
本文是作者通过视频学习后作为笔记记录,如有雷同还请见谅,本人职场菜鸟,刚入门学习,欢迎大佬们指点批评,一起学习一起进步
网友评论