0


ZooKeeper实现分布式锁

Lock
publicinterfaceLock{publicvoidlock();publicvoidunlock();}
ZkLock
/**
 * 使用ZooKeeper实现分布式锁
 * */publicclassZkLockimplementsLock{privateCuratorFramework client;privatefinalString zkPath;privateInteger count;// 记录获取锁的次数,实现可重入锁privatefinalString subNodePathPrefix;privateString lockedPath;privateString preNodePath;privateString subShortPath;privateThread thread;publicZkLock(CuratorFramework client,String zkPath)throwsException{this.client = client;this.zkPath = zkPath;
        subNodePathPrefix ="node-";
        count =0;init();}privatevoidinit()throwsException{synchronized(ZkLock.class){Stat stat;
            stat = client.checkExists().forPath(zkPath);if(stat ==null)
                client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(zkPath);}}@Overridepublicvoidlock(){if(thread ==Thread.currentThread()){// 实现可重入锁
            count +=1;return;}if(lockInternal()){
            thread =Thread.currentThread();
            count +=1;}}/**
     * 上锁函数
     * */privatebooleanlockInternal(){try{boolean locked =tryLock();// 尝试上锁if(locked)returntrue;// 上锁失败,阻塞等待while(!locked)
                locked =await();returntrue;}catch(Exception e){
            e.printStackTrace();}returnfalse;}privatebooleantryLock()throwsException{// 为此上锁请求建立临时有序节点
        lockedPath = client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath(zkPath +"/"+ subNodePathPrefix);if(lockedPath ==null){thrownewException();}// 获取锁节点下面所有的上锁请求节点,判断该上锁请求节点的位置,若为首位则获得锁,否则尝试上锁失败
        subShortPath =getShortPath(lockedPath);List<String> waiters =getWaiters();if(checkIsHeadNode(waiters))returntrue;int index =Collections.binarySearch(waiters, subShortPath);if(index <0)thrownewException();
        preNodePath = zkPath +"/"+ waiters.get(index -1);returnfalse;}privateStringgetShortPath(String path){int index = path.lastIndexOf(zkPath +"/");if(index >=0){
            index += zkPath.length()+1;return index <= path.length()? path.substring(index):"";}returnnull;}privatebooleancheckIsHeadNode(List<String> waiters){Collections.sort(waiters);return subShortPath.equals(waiters.get(0));}privateList<String>getWaiters()throwsException{return client.getChildren().forPath(zkPath);}privatebooleanawait()throwsException{if(preNodePath ==null)thrownewException();CountDownLatch latch =newCountDownLatch(1);
        client.getData().usingWatcher((Watcher) watchedEvent -> latch.countDown()).forPath(preNodePath);
        latch.await();returntrue;}/**
     * 解锁函数
     * */@Overridepublicvoidunlock(){if(!thread.equals(Thread.currentThread()))return;// 检查重入次数
        count -=1;if(count >0)return;try{
            client.delete().forPath(lockedPath);}catch(Exception e){
            e.printStackTrace();}}}
标签: 分布式 zookeeper

本文转载自: https://blog.csdn.net/m0_46278903/article/details/132301131
版权归原作者 enginelong 所有, 如有侵权,请联系我们删除。

“ZooKeeper实现分布式锁”的评论:

还没有评论