1. 程式人生 > >ZooKeeper Watcher執行順序 ********************

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