设为首页 加入收藏

TOP

基于 ZooKeeper 的分布式锁和队列(三)
2017-10-22 06:06:45 】 浏览:773
Tags:基于 ZooKeeper 分布式 队列
if (names.isEmpty()) { LOG.warn("No children in: " + dir + " when we've just " + "created one! Lets recreate it..."); // lets force the recreation of the id id = null; } else { // lets sort them explicitly (though they do seem to come back in order ususally :) SortedSet<ZNodeName> sortedNames = new TreeSet<ZNodeName>(); for (String name : names) { sortedNames.add(new ZNodeName(dir + "/" + name)); } ownerId = sortedNames.first().getName(); SortedSet<ZNodeName> lessThanMe = sortedNames.headSet(idName); if (!lessThanMe.isEmpty()) { ZNodeName lastChildName = lessThanMe.last(); lastChildId = lastChildName.getName(); if (LOG.isDebugEnabled()) { LOG.debug("watching less than me node: " + lastChildId); } Stat stat = zookeeper.exists(lastChildId, new LockWatcher()); if (stat != null) { return Boolean.FALSE; } else { LOG.warn("Could not find the" + " stats for less than me: " + lastChildName.getName()); } } else { if (isOwner()) { if (callback != null) { callback.lockAcquired(); } return Boolean.TRUE; } } } } } while (id == null); return Boolean.FALSE; } }; /** * Attempts to acquire the exclusive write lock returning whether or not it was * acquired. Note that the exclusive lock may be acquired some time later after * this method has been invoked due to the current lock owner going away. */ public synchronized boolean lock() throws KeeperException, InterruptedException { if (isClosed()) { return false; } ensurePathExists(dir); return (Boolean) retryOperation(zop); } /** * return the parent dir for lock * @return the parent dir used for locks. */ public String getDir() { return dir; } /** * Returns true if this node is the owner of the * lock (or the leader) */ public boolean isOwner() { return id != null && ownerId != null && id.equals(ownerId); } /** * return the id for this lock * @return the id for this lock */ public String getId() { return this.id; } }

注意这里的lock,可能会失败,会尝试多次,每次失败后会Sleep一段时间。

PS:官方的代码有个小bug,id和ownerId应该都是全路径,即id = dir + “/” + name;原代码在findPrefixInChildren里有问题。

用于辅助节点大小顺序排序的类:

package org.apache.zookeeper.recipes.lock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Represents an ephemeral znode name which has an ordered sequence number and
 * can be sorted in order
 * 
 */
class ZNodeName implements Comparable<ZNodeName> {
    private final String name;
    private String prefix;
    private int sequence = -1;
    private static final Logger LOG = LoggerFactory.getLogger(ZNodeName.class);

    public ZNodeName(String name) {
        if (name == null) {
            throw new NullPointerException("id cannot be null");
        }
        this.name = name;
        this.prefix = name;
        int idx = name.lastIndexOf('-');
        if (idx >= 0) {
            this.prefix = name.substring(0, idx);
            try {
                this.sequence = Integer.parseInt(name.substring(idx + 1));
                // If an exception occurred we misdetected a sequence suffix,
                // so return -1.
            } catch (NumberFormatException e) {
                LOG.info("Number format exception for " + idx, e);
            } catch (ArrayIndexOutOfBoundsException e) {
                LOG.info("Array out of bounds for " + idx, e);
            }
        }
    }

    @Override
    public String toString() {
        return name.toString();
    }

    @Ove
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 3/9/9
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇就是要你懂 Java 中 volatile 关.. 下一篇基于 Spring Boot 的天气预报服务

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目