有如下三个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实例时,相同的事件不会重复执行。
例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