博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ZooKeeper.分布式锁
阅读量:6802 次
发布时间:2019-06-26

本文共 3775 字,大约阅读时间需要 12 分钟。

hot3.png

#ZooKeeper.分布式锁

  • 看了好多版本的分布式锁,大同小异,其中有几个自旋exists监听节点,觉得很笨,那就再造个轮子吧
  • 思路无非都是相同的,利用ZooKeeper强一致特性
  1. 进程并发在固定父节点下创建不同的临时节点
  2. 查看创建的子节点,排序,取第一个,等于自己的节点,算获取到锁,执行操作,其他监听第一个节点,进入等待
  3. 第一个节点变动,所有机器收到事件,唤醒线程,删除自己的节点,进入步骤1
  • CountDownLatch 比较简洁,但是还是lock更直白,更明确。

tips

  • 这个轮子仅仅是个toy,真正生产环境考虑更多,如释放锁失败异常各种情况
public class ZKLock implements Lock{		private static Logger log = Logger.getLogger(ZKLock.class.getSimpleName());		private ZooKeeper zookpeer; 	private List
acl = ZooDefs.Ids.OPEN_ACL_UNSAFE; private static final String ROOT = "/lock"; private byte[] b = new byte[]{1}; private String lock; private ReentrantLock reenLock = new ReentrantLock(); private Condition condition = reenLock.newCondition(); //private CountDownLatch c; private int i; public ZKLock(String zookpeer,int i) { try { this.i = i; this.zookpeer = new ZooKeeper(zookpeer,3000,new Watcher(){ @Override public void process(WatchedEvent event) { System.out.println("==启动回调=="); }}); init(); } catch (IOException e) { } } @Override public boolean tryLock() { reenLock.lock(); try { System.out.println("==================="); System.out.println("开始抢锁 机器" + i); //c = new CountDownLatch(1); String myLock = zookpeer.create(getLockName(), b, acl, CreateMode.EPHEMERAL); this.lock = getFirstNode(); if(myLock.equals(this.lock)) { //获取到锁 System.out.println("我获得锁,我是 机器" + i + ":" + this.lock + " !!!!!!!!!!!!"); } else { System.out.println("我没抢到锁 机器" + i); } reg(zookpeer); condition.await(); //c.await(); System.out.println("释放锁 机器:" + i); if(zookpeer.exists(myLock, false) != null) { zookpeer.delete(myLock, -1); } } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); }finally{ reenLock.unlock(); } return false; } //初始化锁目录 public void init(){ try { if(zookpeer.exists(ROOT, false) == null) { zookpeer.create(ROOT,b, acl, CreateMode.PERSISTENT); } } catch (KeeperException e) { log.log(Level.WARNING,"root already exist",e); } catch (InterruptedException e) { log.log(Level.SEVERE,"connection fail"); } } public void reg(ZooKeeper zk) { try { zk.exists(lock, new M()); } catch (KeeperException e) { } catch (InterruptedException e) { } } class M implements Watcher{ @Override public void process(WatchedEvent event) { reenLock.lock(); try { System.out.println("节点变更 机器i" + i); //c.countDown(); condition.signal(); reg(zookpeer); } finally{ reenLock.unlock(); } } } @Override public void lock() { while(true){ tryLock(); } } private String getFirstNode() throws KeeperException, InterruptedException { List
children = zookpeer.getChildren(ROOT, false); Collections.sort(children); System.out.println("当前节点:" + Arrays.toString(children.toArray())); return ROOT + "/" + children.get(0); } private String getLockName() { String name = UUID.randomUUID().toString(); return ROOT + "/" + name.substring(0,name.indexOf("-")); } .....}
//3线程模拟争夺 手动删除节点,可看到重新争锁public class LockWatch {	public static void main(String[] args) throws Exception {		ExecutorService p = Executors.newCachedThreadPool();		for(int i = 0; i < 3; i ++) {			p.submit(new T(i));		}	}}class T implements Runnable{		private int i;		public T(int i){		this.i = i;	}	@Override	public void run() {		final ZKLock z = new ZKLock("127.0.0.1",i);		z.lock();	}}
==启动回调====启动回调====启动回调===========================================================开始抢锁 机器2开始抢锁 机器0开始抢锁 机器1当前节点:[a63a788c, c61a117b, decc9d68]当前节点:[a63a788c, c61a117b, decc9d68]我没抢到锁  机器1当前节点:[a63a788c, c61a117b, decc9d68]我没抢到锁  机器0我获得锁,我是 机器2:/lock/a63a788c !!!!!!!!!!!!节点变更 机器i2节点变更 机器i1节点变更 机器i0释放锁 机器:1释放锁 机器:0释放锁 机器:2

转载于:https://my.oschina.net/u/1432304/blog/908980

你可能感兴趣的文章
XSS研究4-来自外部的XSS攻击的防范
查看>>
Spring知识点总结-1
查看>>
微软私有云分享(R2)21 BMC提升B格
查看>>
MDSF:如何使用GMF来做TOGAF建模工具
查看>>
Spring Security简介
查看>>
打造一流的研发中心
查看>>
MCollective架构篇3-Puppet插件的部署及测试
查看>>
配置GNS使用CRT连接
查看>>
Java:集合类性能分析
查看>>
《简约至上:交互设计四策略》导读
查看>>
Spread for Windows Forms快速入门(3)---行列操作
查看>>
Azure手把手系列 3:把IT的钱花在刀刃上
查看>>
【Android游戏开发二十二】(图文详解)游戏中灵活实现动画播放!
查看>>
西门子Prodave5.5使用说明及VC示例
查看>>
创建Server 2012 VHDX虚拟磁盘模板
查看>>
深入探索Java对象的序列化
查看>>
IE调试网页之五:使用 F12 开发人员工具调试 JavaScript 错误 (Windows)
查看>>
asp.net文件上传进度条控件(破解版~没有时间限制) 多项自定义
查看>>
有意思的字符串拘留实验
查看>>
Cuckoo hash算法分析——其根本思想和bloom filter一致 增加hash函数来解决碰撞 节省了空间但代价是查找次数增加...
查看>>