final DictionariesCompiler compiler = (DictionariesCompiler) compilerClass .newInstance(); new Function() { public void run() throws Exception { // 编译词典-对词典进行可能的处理,以符合分词器的要求 if (compiler.shouldCompile(p)) { Dictionaries dictionaries = readUnCompiledDictionaries(p); Paoding tempPaoding = createPaodingWithKnives(p); setDictionaries(tempPaoding, dictionaries); compiler.compile(dictionaries, tempPaoding, p); } // 使用编译后的词典 final Dictionaries dictionaries = compiler .readCompliedDictionaries(p); setDictionaries(finalPaoding, dictionaries); // 启动字典动态转载/卸载检测器 // 侦测时间间隔(秒)。默认为60秒。如果设置为0或负数则表示不需要进行检测 String intervalStr = getProperty(p, Constants.DIC_DETECTOR_INTERVAL); int interval = Integer.parseInt(intervalStr); if (interval > 0) { dictionaries.startDetecting(interval, new DifferenceListener() { public void on(Difference diff) throws Exception { dictionaries.stopDetecting(); // 此处调用run方法,以当检测到**编译后**的词典变更/删除/增加时, // 重新编译源词典、重新创建并启动dictionaries自检测 run(); } }); } } }.run();
首先我们看到一个function,他有个run方法,里面有个监听器,当条件成立,这个监听器会执行这个run方法。run方法的作用是设置字典对象。
我们在run方法里改变的是finalPaoding,但是finalPaoding=Paoding。所以我们改变的就是自身。
当然这里的run方法不是直接去和监听器打交道,中间有个Detector,run方法把Listener和检查的时间间隔都设置到Detector里去,剩下的事情就有Detector来完成了。
Detector会怎么做呢。他会执行自己的start方法:
public void start(boolean daemon) { if (lastSnapshot == null) { lastSnapshot = flash(); } thread = new Thread(this); thread.setDaemon(daemon); thread.start(); }
这个start方法会新创建个自己的线程,再来看看Detector的run方法:他会
listener.on(diff);, 就是触发监听器。这个监听器的on方法在最原始的run方法中已经定义了,其实就是调用run方法自己。这样新的一轮就开始,然后每到监听的时间间隔就会重新开始一轮,这样不断下去。