网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 
中国网管联盟
Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道
 当前位置: > bitsCN.com > JAVA > 开源技术 > Spring > Heritrix的多线程ToeThread和ToePool  

Heritrix的多线程ToeThread和ToePool

2008-05-06  作者:bitsCN整理  来源:中国网管联盟  点评 投稿 收藏

    想要更有效更快速的抓取网页内容,则必须采用多线程。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) 网管网www.bitscn.com
    {
     targetSize = newsize;
     int difference = newsize - getToeCount(); 网管有家www.bitscn.net

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

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

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

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

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

网管论坛bbs_bitsCN_com

TAGs         线程   //   方法   处理   链接   ToePool   toes   ToeThread      
 上一篇:应用spring示例开发网站构思   下一篇:Spring 与 Log4J 进行动态日志配置切换
Heritrix的多线程ToeThread和ToePool 评论:
loading.. 评论加载中…
评论:请自觉遵守互联网相关政策法规,评论不得超过250字。

验证码: 注册用户
本类热门排行:
最新推荐文章:
网管论坛交流: