zookeeper-分布式锁的代码实现-【每日五分钟搞定大数据】

 本文涉及到几个zookeeper简单的知识点,永久节点、有序节点、watch机制。比较基础,熟悉的就别看了跳过这篇吧

  • 每个线程在/locks节点下创建一个临时有序节点test_lock_0000000040
  • 获得/locks节点下所有子节点A、B、C,排序获得最小值
  • 若当前节点B为最小值则获得锁,执行业务逻辑
  • 若当前节点B不是最小值则watch比自己小1的节点A,节点A存在则await,否则获得锁

总结:临时有序节点排序后watch比自己小1的节点。

下面看代码

1.线程初始化

创建一个名字为lockName的永久节点(只有永久节点才可以创建子节点)

DistributedLock(String url, String lockName) {     this.lockName = lockName;     try {         zkConn = new ZooKeeper(url, sessionTimeout, this);         if (zkConn.exists(ROOT_LOCK, false) == null)             zkConn.create(ROOT_LOCK, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);     } catch (IOException | InterruptedException | KeeperException e) {         e.printStackTrace();     } }

复习一下:zookeeper的节点有以下几种类型:永久,永久有序,临时,临时有序

public enum CreateMode {     PERSISTENT(0, false, false),     PERSISTENT_SEQUENTIAL(2, false, true),     EPHEMERAL(1, true, false),     EPHEMERAL_SEQUENTIAL(3, true, true);

2.线程尝试获得锁tryLock

创建临时有序节点,会在你的lockName后面加上一串编号,例如/locks/test_lock_0000000035

CURRENT_LOCK = zkConn.create(ROOT_LOCK + "/" + lockName + splitStr, new byte[0],         ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

获取当前lockName下的所有子临时节点

List<String> subNodes = zkConn.getChildren(ROOT_LOCK, false);

把名字都取出来放进list排个序

List<String> lockObjects = new ArrayList<>(); for (String node : subNodes) {     String _node = node.split(splitStr)[0];     if (_node.equals(lockName)) lockObjects.add(node); }

若当前节点为最小节点,则直接获取锁成功

if (CURRENT_LOCK.equals(ROOT_LOCK + "/" + lockObjects.get(0))) {     return true; }

若不是最小节点,开始等待,见下一步。

关键字:

50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信