5.zk实现-分布式排它锁
来源:互联网 发布:2017手机淘宝装修教程 编辑:程序博客网 时间:2024/05/29 09:32
1.介绍
排它锁::也场称为写锁,某个时间段内只允许一个事务持有锁,其他事务等他别人释放
2.实现思路
(1)定义锁:
创建一个数据节点test/lock来表示锁。test是持久节点,lock为子节点临时节点。
(2)获取锁:
所有客户端的zk实例尝试创建一个lock节点,最终只能有一个创建成功。创建成功的zk实例认为获取锁执行自己的server逻辑,创建失败的锁需要监听test下面子节点变更的watcher来监听别人是否释放了锁。
(3)释放锁:
创建成功的zk实例在机器宕机(zk实例销毁)时zk自动删除lock节点。或者server逻辑执行完毕之后zk实例主动删除结点,其他监听的zk实例再去争夺锁。
(4)整个过程:
zk实例监听watcher然后尝试创建节点。
如果创建成功在回调方法中执行业务逻辑然后监听watcher释放节点发出delete-event给其他监听者。
如果创建失败在回调方法中监听watcher接收其他持锁者的delete-event。监听到持锁着的delete-event后在自己的回调中再次监听warcher并尝试创建节点。
3.测试
package zkTest.test;import java.io.IOException;import java.util.Date;import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException;import org.apache.zookeeper.KeeperException.NodeExistsException;import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.ZooKeeper; public class zk_locks implements Watcher { //zk实例应该为类变量 private ZooKeeper zk; private String path ; //构造函数 public zk_locks(String zkServer,int timeOut,String path) throws IOException{ this.path = path; this.zk=new ZooKeeper(zkServer, timeOut, this); } //创建节点 public void createNode() throws KeeperException, InterruptedException { zk.create(path,"".getBytes(),Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL); } //持锁成功后的业务逻辑,执行完释放锁 public void working(){ Thread thread = new Thread(new Runnable() {public void run() {try { System.out.println(new Date()+"持有锁");Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();} finally { try { System.out.println(new Date()+"释放锁"); System.out.println("-------------------"); //主动释放锁zk.delete(path, 0);} catch (InterruptedException | KeeperException e) {e.printStackTrace();}}}}); thread.start(); } //加锁与判断 public void doLock(){ try { //监听这个节点触发回调,注册一次就触发一次 zk.exists(path, true); //创建成功,回调函数NodeCreated //或者创建失败,抛出节点存在异常,回调函数None this.createNode();} catch (NodeExistsException e) {System.out.println("节点已存在,准备重试");} catch (InterruptedException | KeeperException e) { e.printStackTrace();} } @Override public void process(WatchedEvent event) { try { if (KeeperState.SyncConnected == event.getState()) { if (EventType.None == event.getType() && null == event.getPath()) { //第一次创建失败到这里,说明节点已存在,只能监听别人的delete事件 zk.exists(path, true); } //节点创建事件 else if (EventType.NodeCreated == event.getType()) { this.working(); } //节点删除事件 else if (EventType.NodeDeleted == event.getType()) { //监听到比人的delete事件,我再次加锁,可能成功也可能再次失败 this.doLock(); } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws KeeperException, InterruptedException, IOException{ //五个同时加锁 new zk_locks("192.168.88.131:2181", 10000, "/lock").doLock(); new zk_locks("192.168.88.131:2181", 10000, "/lock").doLock(); new zk_locks("192.168.88.131:2181", 10000, "/lock").doLock(); new zk_locks("192.168.88.131:2181", 10000, "/lock").doLock(); new zk_locks("192.168.88.131:2181", 10000, "/lock").doLock(); //等待工作进程从开始到结束 Thread.sleep(10000); } }
4.测试结果
阅读全文
0 0
- 5.zk实现-分布式排它锁
- ZooKeeper分布式排它锁实现
- Zk实现分布式锁
- zk实现分布式锁
- zk实现分布式锁
- zk实现分布式锁
- 利用ZK实现分布式锁
- ZK-分布式锁
- zk实现分布式统一配置管理
- zk-zclient01 监听、分布式锁
- zk实现锁
- 用Callable和CurrentHashMap实现排它锁
- 排它锁,共享锁,乐观锁,排它锁
- 共享锁&排它锁
- 无法获得排它锁
- 锁(排它锁、悲观锁)
- 共享锁与排它锁
- 数据库共享锁与排它锁
- Part2-HttpClient官方教程-Chapter1-基础
- 使用FFMPeg解码显示ts流
- 拓扑排序-邻接矩阵表示
- oracle动态游标中的强类型和弱类型
- ORACLE sid,pid,spid和v$session中的saddr,paddr和taddr总结
- 5.zk实现-分布式排它锁
- freeCodeCamp题目:No repeats please(排列组合题)
- Java 根据银行卡号获取银行名称以及图标
- Lod和MipMap
- 网络流24题
- 按之字形顺序打印二叉树
- kafka官网示例说明--KafkaConsumer
- Swift中的逃逸闭包的理解
- js 和 app交互信息