说到Nutch中要使用中文分词,因为中文分词程序的速度很快,需要分词的每篇文章字数不会达到需要占用其很长时间的程度。因此,对于每篇文章分词的请求可以看作是大量短小线程的请求,此时使用线程池技术是非常合适的,它可以极大减小线程的创建和销毁次数,提高程序的工作效率。
一个比较简单的线程池应该包含线程管理器、工作线程、任务队列以及任务接口。下面结合分词程序来说说如何在分词中使用线程池:
ThreadPool 是我们的线程池管理器,其中含有任务队列、
Request 是任务接口、
ChineseTokenizer 是中文分词程序,具体的任务类,它实现了Request接口、
WorkThread 实现了Java的Runnable接口,其中run()方法会获取线程池中的任务请求,并调用ChineseTokenizer 类中的 tokenize()方法,来完成分词工作。
如下是接口Request的示例:
1 package cn.ac.cintcm.threadpool;
2
3 import java.io.IOException;
4
5 public interface Request {
6 public void tokenize() throws IOException;
7 }
WorkThread 中的run()方法中会有:
1 synchronized (pool.taskList) {
2 // got a task
3 if (pool.taskList.size() > 0) {
4 pool.freeNum--;
5 pool.workingNum++;
6 request = pool.taskList.removeFirst();
7 try {
8 request.tokenize();
9 } catch (IOException e) {
10 e.printStackTrace();
11 }
12 pool.taskList.notifyAll();
13 break;
14 }
15 // wait for task
16 else
17 pool.taskList.wait();
18 }
ChineseTokenizer 会使用到 Lucene的Token类
import java.io.*;
import java.util.*;
import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.nutch.searcher.Query;
public class ChineseTokenizer extends Tokenizer implements Request {
public void tokenize() throws IOException {
//对每一种情况进行一次词语组合,生成一个Lucene的Token
Token token = new Token(currentWordStringBuffer.toString(),
outLineStringBuffer.length(), outLineStringBuffer.length() + outLineStringBuffer.length(), tokenType);
}
} 现在的ChineseTokenizer 类中只实现了,初步的字典匹配分词方法,但是对于普通的垂直搜索方面的应用已经足够了,特定领域的词汇比较固定,而且歧义很少出现,分析网络上文章中特定词语出现的概率,达到阈值之后就可以把这篇文章收录到本地磁盘中了:)
本文依据《创作共用约定》之“署名
-禁止派生
-非商业用途”方式发布,即你可以免费拷贝、分发、呈现和表演当前作品,但是必须基于以下条款:
对于任何二次使用或分发,你必须让其他人明确当前作品的授权条款。
在得到作者的明确允许下,这里的某些条款可以放弃。