今天繼續源碼分析,分析一下org.apache.zookeeper.server下的WatchManager類。node
WatcherManager類用於管理watchers和相應的觸發器。apache
//watchTable表示從節點路徑到watcher集合的映射 private final HashMap<String, HashSet<Watcher>> watchTable = new HashMap<String, HashSet<Watcher>>(); //watch2Paths則表示從watcher到全部節點路徑集合的映射 private final HashMap<Watcher, HashSet<String>> watch2Paths = new HashMap<Watcher, HashSet<String>>();
size方法是同步的,所以在多線程環境下是安全的,其主要做用是獲取watchTable的大小,即遍歷watchTable的值集合,每一個集合大小累加。promise
synchronized int size(){ int result = 0; for(Set<Watcher> watches : watchTable.values()) { result += watches.size(); } return result; }
addWatch方法一樣是同步的,主要用來更新類裏面的上面提到的兩個集合屬性。安全
synchronized void addWatch(String path, Watcher watcher) { //經過傳入的path(節點路徑)從watchTable獲取相應的watcher集合 HashSet<Watcher> list = watchTable.get(path); if (list == null) { //watcher是否爲空,若爲空 // don't waste memory if there are few watches on a node // rehash when the 4th entry is added, doubling size thereafter // seems like a good compromise //新生成watcher集合,並將路徑path和此集合添加至watchTable中 list = new HashSet<Watcher>(4); watchTable.put(path, list); } //將傳入的watcher添加至watcher集合,即完成了path和watcher添加至watchTable的步驟 list.add(watcher); //經過傳入的watcher從watch2Paths中獲取相應的path集合 HashSet<String> paths = watch2Paths.get(watcher); if (paths == null) {// 判斷path集合是否爲空,若爲空 // cnxns typically have many watches, so use default cap here //新生成path集合,並將watcher和paths添加至watch2Paths中 paths = new HashSet<String>(); watch2Paths.put(watcher, paths); } // 將傳入的path(節點路徑)添加至path集合,即完成了path和watcher添加至watch2Paths的步驟 paths.add(path); }
removeWatcher用做從watch2Paths和watchTable中中移除該watcher多線程
synchronized void removeWatcher(Watcher watcher) { //從wach2Paths中移除watcher,並返回watcher對應的path集合 HashSet<String> paths = watch2Paths.remove(watcher); if (paths == null) { return; } for (String p : paths) { //從watcherTable中根據路徑取出相應的watcher集合 HashSet<Watcher> list = watchTable.get(p); if (list != null) { // 從list中移除該watcher list.remove(watcher); // 移除後list爲空,則從watchTable中移出path if (list.size() == 0) { watchTable.remove(p); } } } }
該方法主要用於觸發watch事件,並對事件進行處理。ide
Set<Watcher> triggerWatch(String path, EventType type) { return triggerWatch(path, type, null); } Set<Watcher> triggerWatch(String path, EventType type, Set<Watcher> supress) { // 根據事件類型、鏈接狀態、節點路徑建立WatchedEvent WatchedEvent e = new WatchedEvent(type, KeeperState.SyncConnected, path); HashSet<Watcher> watchers; synchronized (this) { // 從watcher表中移除path,並返回其對應的watcher集合 watchers = watchTable.remove(path); if (watchers == null || watchers.isEmpty()) { if (LOG.isTraceEnabled()) { ZooTrace.logTraceMessage(LOG, ZooTrace.EVENT_DELIVERY_TRACE_MASK, "No watchers for " + path); } return null; } // 遍歷watcher集合 for (Watcher w : watchers) { // 根據watcher從watcher表中取出路徑集合 HashSet<String> paths = watch2Paths.get(w); if (paths != null) { // 若是paths不爲空,則移除傳入路徑path paths.remove(path); } } } // 遍歷watcher集合 for (Watcher w : watchers) { if (supress != null && supress.contains(w)) { continue; } // watcher進行處理 w.process(e); } return watchers; }