zookeeper分布式锁

加锁
在这里插入图片描述
临时节点是随着客户端失去连接而删除,所以不会因客户端宕机而造成锁无法释放

释放锁
在这里插入图片描述
如果是多个线程也是如此的,线程B监听前一个节点(线程A创建的)的状态,线程C监听前一个节点(线程B创建)的状态,这样就像形成了一个等待队列

分布式锁优点缺点
redisset和del执行效率高没有等待锁的队列,只能通过自旋的形式来等待锁。
实现复杂,需要考虑原子性、超时、误删等情形。
zookeeper有等待锁的队列,提高抢占锁的效率添加和删除节点效率低下

redis生产环境上一般使用redission来实现分布式锁
zookeeper一般使用apache curator来实现分布式锁

apache curator教程

  1. 添加依赖
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.13</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>3.2.1</version>
</dependency>
  1. 关键代码
public class A {
    private static CuratorFramework client = getClient();
    private static InterProcessMutex lock = new InterProcessMutex(client, "/test");
    public static int count = 0;

    public void doSomething() {
        try {
            lock.acquire();
            System.out.println(Thread.currentThread().getName() + "begin----------------------");
            System.out.println(Thread.currentThread().getName() + "----------------------");
            System.out.println(Thread.currentThread().getName() + "end----------------------");
            count++;
            lock.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static CuratorFramework getClient() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("127.0.0.1:2181")
                .retryPolicy(retryPolicy)
                .sessionTimeoutMs(6000)
                .connectionTimeoutMs(3000)
                .namespace("demo")
                .build();
        client.start();
        return client;
    }

    public static void closeZk() {
        if (client != null) {
            client.close();
        }
    }

}
  1. Test
public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new A().doSomething();
            }
        };
        for (int i = 0; i < 50; i++) {
            new Thread(runnable).start();
        }
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" + A.count);
        A.closeZk();
    }

核心代码就三行

InterProcessMutex lock = new InterProcessMutex(client, "/lock_name");
lock.acquire();	//加锁
//业务代码
lock.release();	//释放锁

zookeeper增删查改

public class SimpleDemo {
    private static final  int SESSION_TIMEOUT = 20000;
    ZooKeeper zk;
    Watcher wh = new Watcher() {
        @Override
        public void process(WatchedEvent event){
            System.out.println("@@@@@@@@@@@@@" + event.toString());
        }
    };

    private void createZKInstance() throws IOException {
        zk = new ZooKeeper("localhost:2181", SimpleDemo.SESSION_TIMEOUT, this.wh);
    }

    private void ZKOperations() throws KeeperException, InterruptedException {
        zk.create("/zoo2", "myData2".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println(new String(zk.getData("/zoo2", false, null)));
        zk.setData("/zoo2", "shenlan2423".getBytes(), -1);
        System.out.println(new String(zk.getData("/zoo2", false, null)));
        zk.delete("/zoo2", -1);
        System.out.println(zk.exists("/zoo2", false));
    }

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        SimpleDemo dm = new SimpleDemo();
        dm.createZKInstance();
        dm.ZKOperations();
        dm.ZKClose();
    }

    private void ZKClose() throws InterruptedException {
        zk.close();
    }
}

zookeeper不使用框架实现分布式锁

public class DistributedClient {
    private static final int SESSION_TIMEOUT = 5000;
    private String hosts = "localhost:2181";
    private String groupNode = "locks";
    private String subNode = "sub";

    private ZooKeeper zk;
    private String thisPath;
    private String waitPath;

    private CountDownLatch latch = new CountDownLatch(1);

    private void connectZookeeper() throws Exception {
        zk = new ZooKeeper(hosts, SESSION_TIMEOUT, (event) -> {
            try {
                if (event.getState() == Watcher.Event.KeeperState.SyncConnected) {
                    latch.countDown();
                }
                if (event.getType() == Watcher.Event.EventType.NodeDeleted && event.getPath().equals(waitPath)) {
                    doSomething();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        latch.await();
        thisPath = zk.create("/" + groupNode + "/" + subNode, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        Thread.sleep(10);
        List<String> children = zk.getChildren("/" + groupNode, false);
        if (children.size() == 1) {
            doSomething();
        } else {
            String thisNode = thisPath.substring(("/" + groupNode + "/").length());
            Collections.sort(children);
            int index = children.indexOf(thisNode);
            if (index == -1) {

            } else if (index == 0) {
                doSomething();
            } else {
                this.waitPath = "/" + groupNode + "/" + children.get(index - 1);
                zk.getData(waitPath, true, new Stat());
            }
        }
    }

    private void doSomething() throws KeeperException, InterruptedException {
        System.out.println("gain lock: " + thisPath);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("finished: " + thisPath);
            zk.delete(this.thisPath, -1);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    try {
                        DistributedClient dl = new DistributedClient();
                        dl.connectZookeeper();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
        Thread.sleep(Long.MAX_VALUE);
    }
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值