栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 云计算 > 云平台

zooKeeper 单node实现分布式锁

云平台 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

zooKeeper 单node实现分布式锁

package zk;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;


public class ZKLock {
    //使用静态变量保证一个JVM里面只有一个ZKLock下只有一个ZooKeeper
    private static ZooKeeper zooKeeper;
    //zk节点
    private String path;
    //静太重入锁
    private static ReentrantLock reentrantLock=new ReentrantLock();

    public ZKLock(String host,String path){
        this.path=path;
        //多实例环境下保存只初始化一次
        if(zooKeeper==null){
            reentrantLock.lock();
            if(zooKeeper==null) initZK(host);
            reentrantLock.unlock();
        }

    }

    

    public void lock() {

        //先保证单个JVM锁
        reentrantLock.lock();

        //再保证分布式锁
        distributeLock();

        reentrantLock.unlock();
    }

    private void distributeLock(){
        //保存一个当前线程信息
        Thread t=Thread.currentThread();
        //再保证分布式锁
        while (true){
            Stat stat=null;
            try {
                stat = zooKeeper.exists(path, new Watcher() {
                    @Override
                    public void process(WatchedEvent watchedEvent) {
                        //此方法为另一个线程调用
                        if(watchedEvent.getType()== Event.EventType.NodeDeleted){
                            //用当前线程unpark
                            LockSupport.unpark(t);
                        }

                    }
                });
            }catch (Exception ex){
                ex.printStackTrace();
            }
            //是否成功获取到了锁
            boolean lk=false;
            if(stat==null){
                //创建锁节点
                try {
                    //因为判断是否存在一个节点和创建一个节点并不是原子操作,
                    // 所以这里有可能会创建失败,所以需要注意NodeExistsException异常情况
                    zooKeeper.create(path, "0000".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
                    lk=true;
                }catch (KeeperException.NodeExistsException ex){
                    //让出CPU调度,进入下一次尝试获取锁
                    Thread.yield();
                    continue;
                }catch (Exception ex){

                }
                if(lk){
                    break;
                }
            }else{
                LockSupport.park();
            }
        }

    }

    
    public void release(){
        //删除NODE
        try {
            zooKeeper.delete(path,-1);
        }catch (Exception ex){}
    }

    //初始化zooKeeper变量
    private static void initZK(String host){
        try {
            zooKeeper=new ZooKeeper(host, 10000000, new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {

                }
            });
        }catch (Exception ex){}
    }

}

测试
package zk;

public class zkTest {

    static int i=0;

    public static void main(String[] args) throws Exception {

        String host="192.168.1.235:2181";

        ZKLock lock=new ZKLock(host,"/lock");

        ZKLock lock2=new ZKLock(host,"/lock");

        for (int j = 0; j < 1000; j++) {
            int finalJ = j;
            new Thread(()->{
                lock.lock();
                i++;
                lock.release();
            }).start();

        }
        for (int j = 0; j < 1000; j++) {
            int finalJ = j;
            new Thread(()->{
                lock2.lock();
                i++;
                lock2.release();
            }).start();

        }
        while (Thread.activeCount()>3){
            //System.out.println(Thread.activeCount());
            Thread.yield();
        }
        
        System.out.println("最终结果:"+i);

    }

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/896756.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号