Java ZooKeeper序列并发

Java ZooKeeper序列并发,java,apache-zookeeper,Java,Apache Zookeeper,我使用以下代码在并发系统中生成一个唯一的id编号序列: String idNodePath = "/somenode/idNode"; Stat stat = null; Integer id = null; try{ stat = zk.setData(idNodePath, new byte[0], -1); id = stat.getVersion(); } catch ( KeeperException e){

我使用以下代码在并发系统中生成一个唯一的
id
编号序列:

    String idNodePath = "/somenode/idNode";
    Stat stat = null;
    Integer id = null;
    try{
        stat = zk.setData(idNodePath, new byte[0], -1);
        id = stat.getVersion();
    } catch ( KeeperException e){
        zk.create(idNodePath, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zk.getData(idNodePath, false, stat);
    }
我担心这可能不是使用Zookeeper实现这一目标的正确方法,尽管我确实发现其他人也在使用类似的方法:这给了我一点安慰

我的问题是:在并发系统中这样做安全吗?是否保证
id
编号是唯一的和顺序的?(即,当所有并发进程/机器的所有
id
编号放在一起时,没有间隙)


更新:修复由AlexR指出的代码中的
NullPointerException
错误(谢谢!)

您的代码肯定包含错误。查看
stat
变量。它在
try
块之前为
null
,并在那里初始化。但是如果抛出了
KeeperException
,您将到达下一行

int id = stat.getVersion();
因为
stat
仍然为空,所以抛出
NullPointerException

现在关于并发。据我所知,zk是你们班的一员。在这种情况下,代码也不正确。考虑两个线程。首先计算行
stat=zk.setData()
,即更改
zk
的状态。Second到达同一行并对其进行计算,即根据其参数更改共享对象
zk
的状态。然后第一个线程调用
zk.getVersion()
,即根据线程2设置的状态获取版本


我不能给你任何关于修改代码的建议,因为我不知道你想要实现什么。如果你能详细解释你的任务,你可能会得到更好的建议如何实施它

感谢您指出空指针错误,我将修复它。至于
zk
对象,它的每个实例只会在一个线程中被调用,所以我认为这里没有问题。我主要关心的是,如果这段代码运行在两个不同的服务器上,每个服务器都连接到ZK集成中的两个不同服务器上,会怎么样?ZK是否保证集成中跨服务器的并发性和顺序性?