ZooKeeper Watcher执行顺序 ********************

有如下三个wathcer

 zk.extist(rootpath+childpath,new ExistWater())

zk.getData(rootpath+childpath,new DataWatcher());

zk.getChildren(rootpath,new ChilrenWatcher());

ZooKeeper Watcher测试顺序如下

一、给同一个节点通过不同的方式注册不同的watcher实例(使用不同的对象)

1、当删除rootpath+childpath节点时,ExistWater跟DataWatcher肯定比ChilrenWatcher先执行,ExistWater跟DataWatcher的顺序是不定的

2、当修改rootpath+childpath节点数据时,ChilrenWatcher是不会触发的,ExistWater跟DataWatcher执行的顺序跟他们的注册时间有关系

    例1:     zk.extist(rootpath+childpath,new ExistWater())

                  zk.getData(rootpath+childpath,new DataWatcher());

    如果是extist在getData前面,那么ExistWater先执行

    例2:   zk.getData(rootpath+childpath,new DataWatcher());

                 zk.extist(rootpath+childpath,new ExistWater())

    如果是getData在extist前面,那么DataWatcher先执行

3、当新增rootpath+childpath节点的时候,DataWatcher是不存在的,ExistWater在ChilrenWatcher之前执行

另外需要说明的是Watcher的执行时同步的,一定是一个执行完之后再执行另一个的,不是同时进行的,比如执行ExistWater执行完在执行DataWatcher,不会同时执行的


二、给同一个节点通过不同的方式注册同一个watcher实例(使用同一个对象)

例1:rootpath  path=rootpath+childpath

ExistWather existsWather=new ExistWather();

zk.getData(path,existsWather, null);
zk.exists(path, existsWather);

zk.setData(path,"aa".getByte(),-1)或者zk.delete(path,-1)时,existsWather只会执行一次

结论:一个watch实例被注册到同一个节点的getData()和exists(),节点被修改、删除,仅触发一次watch

例2:rootpath  path=rootpath+childpath

ExistWather existsWather=new ExistWather();

zk.getData(path,existsWather, null);
zk.exists(path, existsWather);

zk.getChildren(rootpath,existsWather);

当zk.setData(path,"aa".getByte(),-1)或者zk.delete(path,-1)时,existsWather会执行2次,

结果是:

NodeDeleted
NodeChildrenChanged
也就是说exists或者getData的会执行一次,并且在getChildren上的wathcer之前,然后getChildren上的watcher也会执行一次

PS:我认为可以这么理解:当exists跟getData注册同一个watcher实例的时候,他们的事件是一致的,都是NodeDeleted或则NodeDataChanged,所以只需要执行一次,getChildren上注册的watcher触发的时候执行的事件是NodeChildrenChanged,跟exists和getData不一样,所以需要再执行一次,即当注册同一个watcher实例时,相同的事件不会重复执行。

 

                 同一个watcher注册在不同的getChildren或exists或getData时,如果XX事件是一致的只会触发一次

例3:

zk.getData(path,new ExistWather(), null);
zk.exists(path, new ExistWather());

当zk.setData(path,"aa".getByte(),-1)或者zk.delete(path,-1)时,existsWather会执行2次,因为是注册watcher不是同一个实例


三、同一个节点使用相同的方式注册不同的watcher实例

例1

zk.getData(path,new ExistWather(), null);

zk.getData(path,new DataWatcher(), null);

zk.getData(path,new ChilrenWatcher(), null);

那么ExistWather、DataWatcher、ChilrenWatcher都会被触发执行,但是执行顺序是不定的

结论:当使用zk.exists、zk.getData、zk.getChildren多次注册不同的实例时,多个watcher都会被执行,执行顺序是不定的

例2

zk.getData(path,new ExistWather(), null);

zk.getData(path,new ExistWather(), null);

zk.getData(path,new ExistWather(), null);

那么ExistWather会被触发3次执行

结论:当使用zk.exists、zk.getData、zk.getChildren多次注册不同的实例时,多个watcher都会被执行,执行顺序是不定的

其实例1跟例2是一样的,都是多次注册不同的实例,这里再举例出来,是为了强调下什么是不同实例的概念

例3

ExistWather watcher=new ExistWather()

zk.getData(path,watcher, null);

zk.getData(path,watcher, null);

zk.getData(path,watcher, null);

那么watcher只会触发一次

结论:当使用zk.exists、zk.getData、zk.getChildren多次注册同一个实例时,只会触发一次watcher

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值