Chinaunix首页 | 论坛 | 博客
  • 博客访问: 673768
  • 博文数量: 779
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 5000
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-27 13:28
文章分类

全部博文(779)

文章存档

2011年(1)

2008年(778)

我的朋友

分类:

2008-10-27 13:28:23

    想要更有效更快速的抓取网页内容,则必须采用多线程。Heritrix中提供了一个标准的线程池ToePool,它用于管理所有的抓取线程。 ToePool和ToeThread都位于org.archive.crawler.framework包中。前面已经说过ToePool的初始化,是在CrawlController的initialize()方法中完成的。来看一下ToePool以及ToeThread是如何被初始化的。以下代码是在CrawlController中用于对ToePool进行初始化的。
    构造函数 toePool = new ToePool(this);
    // 按order.xml中的配置,实例化并启动线程
    toePool.setSize(order.getMaxToes()); ToePool的构造函数很简单,如下所示 public ToePool(CrawlController c) {
     super("ToeThreads");
     this.controller = c;
    } 它仅仅是调用了父类java.lang.ThreadGroup的构造函数,同时,将注入的CrawlController赋给类变量。这样,便建立起了一个线程池的实例了。但是,那些真正的工作线程又是如何建立的呢?
    下面来看一下线程池中的setSize(int)方法。从名称上看,这个方法很像是一个普通的赋值方法,但实际上,它并不是那么简单。 public void setSize(int newsize)
    {
     targetSize = newsize;
     int difference = newsize - getToeCount();

     // 如果发现线程池中的实际线程数量小于应有的数量
     // 则启动新的线程
     if (difference > 0) {
          for(int i = 1; i <= difference; i++) {
           // 启动新线程
              startNewThread();
      }
     }
     // 如果线程池中的线程数量已经达到需要
     else
     {

          int retainedToes = targetSize;
          // 将线程池中的线程管理起来放入数组中
          Thread[] toes = this.getToes();

          // 循环去除多余的线程
          for (int i = 0; i < toes.length ; i++) {
              if(!(toes[i] instanceof ToeThread)) {
                   continue;
              }
              retainedToes--;
              if (retainedToes>=0) {
                   continue;
              }
              ToeThread tt = (ToeThread)toes[i];
              tt.retire();
          }
     }
    }

    // 用于取得所有属于当前线程池的线程
    private Thread[] getToes()
    {
     Thread[] toes = new Thread[activeCount()+10];
     // 由于ToePool继承自java.lang.ThreadGroup类
     // 因此当调用enumerate(Thread[] toes)方法时,
     // 实际上是将所有该ThreadGroup中开辟的线程放入
     // toes这个数组中,以备后面的管理
     this.enumerate(toes);
     return toes;
    }

    // 开启一个新线程
    private synchronized void startNewThread()
    {
     ToeThread newThread = new ToeThread(this, nextSerialNumber++);
     newThread.setPriority(DEFAULT_TOE_PRIORITY);
     newThread.start();
    } 通过上面的代码可以得出这样的结论:线程池本身在创建的时候,并没有任何活动的线程实例,只有当它的setSize方法被调用时,才有可能创建新线程;如果当setSize方法被调用多次而传入不同的参数时,线程池会根据参数里所设定的值的大小,来决定池中所管理线程数量的增减。

[1]  

【责编:Ken】

--------------------next---------------------

阅读(290) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~