空心|最全分布式锁设计方案( 四 )

  • 测试类:测试整合curator框架是否成功
@SpringBootTest(classes = {DistributedLockApplication.class})@RunWith(SpringRunner.class)public class DistributedLockApplicationTests {@Autowired private CuratorFramework curatorFramework; @Test public void contextLoads() {curatorFramework.start();try {curatorFramework.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/zhusl", "test".getBytes());} catch (Exception e) {e.printStackTrace();} }}在确保zookeeper成功启动了的情况下 , 执行这个单元测试 , 最后回到linux中 , 用zkCli.sh连接 , 查看是否成功创建节点 。
2、使用Curator做分布式锁:
Curator封装了很多锁 , 比如可重入共享锁、不可重入共享锁、可重入读写锁、联锁等 。 具体可以参考官网:curator分布式锁的用法 。
  • ZookeeperUtil.java:工具类 , 封装获取锁 , 释放锁等方法 。 这里主要简单地封装了上面说的四种锁 , 仅供参考 。
@Component@Slf4jpublic class ZookeeperUtil { private static CuratorFramework curatorFramework;private static InterProcessLock lock; /** 持久节点 */ private final static String ROOT_PATH = "/lock/";/** 可重入共享锁 */ private static InterProcessMutex interProcessMutex; /** 不可重入共享锁 */ private static InterProcessSemaphoreMutex interProcessSemaphoreMutex; /** 可重入读写锁 */ private static InterProcessReadWriteLock interProcessReadWriteLock; /** 多共享锁(将多把锁当成一把来用) */ private static InterProcessMultiLock interProcessMultiLock; @Autowired private void setCuratorFramework(CuratorFramework curatorFramework) {ZookeeperUtil.curatorFramework = curatorFramework;ZookeeperUtil.curatorFramework.start(); } /*** 获取可重入排他锁** @param lockName* @return*/ public static boolean interProcessMutex(String lockName) {interProcessMutex = new InterProcessMutex(curatorFramework, ROOT_PATH + lockName);lock = interProcessMutex;return acquireLock(lockName, lock); } /*** 获取不可重入排他锁** @param lockName* @return*/ public static boolean interProcessSemaphoreMutex(String lockName) {interProcessSemaphoreMutex = new InterProcessSemaphoreMutex(curatorFramework, ROOT_PATH + lockName);lock = interProcessSemaphoreMutex;return acquireLock(lockName, lock); } /*** 获取可重入读锁** @param lockName* @return*/ public static boolean interProcessReadLock(String lockName) {interProcessReadWriteLock = new InterProcessReadWriteLock(curatorFramework, ROOT_PATH + lockName);lock = interProcessReadWriteLock.readLock();return acquireLock(lockName, lock); } /*** 获取可重入写锁** @param lockName* @return*/ public static boolean interProcessWriteLock(String lockName) {interProcessReadWriteLock = new InterProcessReadWriteLock(curatorFramework, ROOT_PATH + lockName);lock = interProcessReadWriteLock.writeLock();return acquireLock(lockName, lock); } /*** 获取联锁(多把锁当成一把来用)* @param lockNames* @return*/ public static boolean interProcessMultiLock(List lockNames) {if (lockNames == null || lockNames.isEmpty()) {log.error("no lockNames found");return false;}interProcessMultiLock = new InterProcessMultiLock(curatorFramework, lockNames);try {if (!interProcessMultiLock.acquire(10, TimeUnit.SECONDS)) {log.info("Thread:" + Thread.currentThread().getId() + " acquire distributed lock fail");return false;} else {log.info("Thread:" + Thread.currentThread().getId() + " acquire distributed lock success");return true;}} catch (Exception e) {log.info("Thread:" + Thread.currentThread().getId() + " release lock occured an exception = " + e);return false;} } /*** 释放锁** @param lockName*/ public static void releaseLock(String lockName) {try {if (lock != nullcuratorFramework.delete().inBackground().forPath(ROOT_PATH + lockName);log.info("Thread:" + Thread.currentThread().getId() + " release lock success");}} catch (Exception e) {log.info("Thread:" + Thread.currentThread().getId() + " release lock occured an exception = " + e);} }/*** 释放联锁*/ public static void releaseMultiLock(List lockNames) {try {if (lockNames == null || lockNames.isEmpty()) {log.error("no no lockNames found to release");return;}if (interProcessMultiLock != nullfor (String lockName : lockNames) {curatorFramework.delete().inBackground().forPath(ROOT_PATH + lockName);}log.info("Thread:" + Thread.currentThread().getId() + " release lock success");}} catch (Exception e) {log.info("Thread:" + Thread.currentThread().getId() + " release lock occured an exception = " + e);} }/*** 获取锁** @param lockName* @param interProcessLock* @return*/ private static boolean acquireLock(String lockName, InterProcessLock interProcessLock) {int flag = 0;try {while (!interProcessLock.acquire(2, TimeUnit.SECONDS)) {flag++;if (flag > 1) {break;}}} catch (Exception e) {log.error("acquire lock occured an exception = " + e);return false;}if (flag > 1) {log.info("Thread:" + Thread.currentThread().getId() + " acquire distributed lock fail");return false;} else {log.info("Thread:" + Thread.currentThread().getId() + " acquire distributed lock success");return true;} }}


推荐阅读