ZooKeeper完全解析(九) 使用Curator来简化ZooKeeper操作之分布式锁的使用

  在上一篇中,我们讲解了如何使用Curator来进行增删改查的操作,链接为 ZooKeeper完全解析(八) 使用Curator来简化ZooKeeper操作之基本使用 ,之前我们使用过ZooKeeper库来实现过分布式锁,链接为 ZooKeeper完全解析(六) 使用ZooKeeper实现分布式锁之实现原理 、 ZooKeeper完全解析(七) 使用ZooKeeper实现分布式锁之Java实现,这一节中,我们将讲解如何如何使用Curator来实现分布式锁。

  Curator使用InterProcessMutex类来实现分布式锁。

一、实例化:

public InterProcessMutex(CuratorFramework client,
                         String path)

首先需要传入 CuratorFramework ,其次需要传入这次锁的path,比如 /data 。

 

二、获取锁:

  获取锁分为两种,一种是一直阻塞线程,直到获取到锁。一种是在指定的时间内获取到锁,获取成功返回true,获取失败返回false,如果没有获取到则返回false。

  1、一直阻塞线程,直到获取到锁:

public void acquire()

 2、在指定时间内获取到锁:

public boolean acquire(long time,
                       TimeUnit unit)

 

三、释放锁:

  注意在完成任务之后,需要调用 release() 方法来释放锁

public void release()

四、示例:

package com.happyheng.Controller;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 *
 * Created by happyheng
 */
@RestController
@RequestMapping("/lock")
public class LockController {

    private static final Logger logger = LoggerFactory.getLogger(LockController.class);

    @Autowired
    private CuratorFramework curatorFramework;

    @RequestMapping("/data")
    public String lockData() {

        int randomInteger = (int) (Math.random() * 10000);

        InterProcessMutex processMutex = new InterProcessMutex(curatorFramework, "/data");
        try {

            logger.info( randomInteger + " 开始获取锁");


            // 开始获取分布式锁
            boolean lockSuccess =  processMutex.acquire(2, TimeUnit.SECONDS);

            if (!lockSuccess) {
                return randomInteger + " 获取失败";
            }


            logger.info( randomInteger + " 获取到锁");

            // 开始模拟执行
            Thread.sleep(3000);

            logger.info( randomInteger + " 执行完成");

            // 释放分布式锁
            processMutex.release();

            logger.info( randomInteger + " 释放锁");
        } catch (Exception e) {
            e.printStackTrace();
            return randomInteger + " error";
        }


        return randomInteger + " 执行完成";
    }


}

上述如果有两个节点都在启动的话,然后同时访问两个节点,其中一个肯定会失败(故意把等待锁的时间设置的比持有锁的时候还要短) ,此为模拟分布式锁中是否成功锁住。如果将等待锁的时间由2s设置为10s,那么同时访问两个项目,会发现有一个节点会执行,等释放完锁之后,另外一个节点才会执行。

 

  下一篇中,我将会讲解如何使用Curator来实现分布式锁,链接为 ZooKeeper完全解析(十) 使用Curator来简化ZooKeeper操作之群首选举

 

你可能感兴趣的:(zookeeper,ZooKeeper)