最简单分布式锁ZK实现方案
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最简单分布式锁ZK实现方案相关的知识,希望对你有一定的参考价值。
分布式锁简单封装
package com.hellojd.cloud.locks.v1; import org.apache.zookeeper.*; import java.io.IOException; import java.util.concurrent.CountDownLatch; import static org.apache.zookeeper.Watcher.Event.KeeperState.SyncConnected; /** * 最简单分布式锁实现方案 */ public class ZookerSession implements Watcher { private CountDownLatch countDownLatch=new CountDownLatch(1); private ZooKeeper zooKeeper; private static class Singleton{ private static ZookerSession instance; static { instance = new ZookerSession(); } public static ZookerSession getInstance(){ return instance; } } public static ZookerSession getInstance(){ return Singleton.getInstance(); } public ZookerSession() { try { this.zooKeeper = new ZooKeeper("192.168.0.10:2181",50000,this); countDownLatch.await(); System.out.println("state: "+zooKeeper.getState()); System.out.println("connection estalished!!"); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } public ZooKeeper getZooKeeper(){return this.zooKeeper;} @Override public void process(WatchedEvent event) { if(event.getState()==SyncConnected){ countDownLatch.countDown(); } } public void releaseDistributeLock(Long id){ String path ="/lock_"+id; try { zooKeeper.delete(path,-1); } catch (InterruptedException e) { e.printStackTrace(); } catch (KeeperException e) { e.printStackTrace(); } } public void acquireDistributeLock(Long id){ String path ="/lock_"+id; try { zooKeeper.create(path,null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); // System.out.println("success to acquire lock "+id); } catch (KeeperException e) { //没有获取到锁 int count=0; while (true){ try{ Thread.sleep(200); zooKeeper.create(path,null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); }catch (InterruptedException e1) { count++; continue; } catch (KeeperException e1) { // e1.printStackTrace(); count++; continue; } // System.out.println("success to acquire lock "+id); break; } } catch (InterruptedException e) { e.printStackTrace(); } } }
2.测试线程
package com.hellojd.cloud.locks.v1; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.data.Stat; /** * 测试线程 */ public class Task implements Runnable { private int loop; private Long lockid; ZookerSession zs; public Task(int loop,Long lockid) { zs = ZookerSession.getInstance(); this.loop = loop; this.lockid = lockid; } @Override public void run() { ZookerSession.getInstance().acquireDistributeLock(lockid); for(int i=0;i<loop;i++){ int count = getcount(); System.out.println(Thread.currentThread().getName()+"-->"+count); count(++count); } zs.releaseDistributeLock(lockid); } //计数 public void count(int count){ try { Stat s = zs.getZooKeeper().exists("/count", false); if(s==null){ System.out.println("count 不存在"); zs.getZooKeeper().create("/count",String.valueOf(count).getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); }else{ zs.getZooKeeper().setData("/count",String.valueOf(count).getBytes(),-1); } } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } public int getcount(){ try { Stat s = zs.getZooKeeper().exists("/count", false); if(s==null){ zs.getZooKeeper().create("/count",String.valueOf(0).getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); return 0; }else{ byte[] data = zs.getZooKeeper().getData("/count", false, null); return Integer.valueOf(new String(data)); } } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return -1; } public static void main(String[] args) { long LOCKID = 2l; for(int i=0;i<100;i++){ new Thread(new Task(1, LOCKID)).start(); } } }
原理:分布式锁通过死循环+实现等待效果。如果线程可以创建节点,则成功获取锁;
释放锁:就是将数据节点在ZK上删除。
缺点:简单且性能低。有风险。如果获取锁的线程中断,导致任务异常。
本文出自 “简单” 博客,请务必保留此出处http://dba10g.blog.51cto.com/764602/1975120
以上是关于最简单分布式锁ZK实现方案的主要内容,如果未能解决你的问题,请参考以下文章