zoukankan      html  css  js  c++  java
  • 一个多线程应用的最佳示例

    刚刚完成一个网站抓取数据的任务,在抓取的时候用到了多线程。

    任务描述:
        有个信息发布网站,按照条件会查询出数据,按页显示,每页15条,每条信息为一个url链接。点击链接再打开一个页面,显示这条的详细信息。

        我们需要做的是把每条的详细信息都抓取下来,保存到数据库中。

    开始我做好了抓取的所有程序,保存到数据库中。
    做完运行,发现速度很慢,因为数据量比较大,大约有30多万条详细信息需要抓取。

    就想到这个用多线程来实现真是再好不过了,开15条线程,一次就把一页的详细信息都抓取下来,不是很快吗?

    后来加上多线程后,一次开16线程,比原来快了很多,呵呵~!

    因为这个工程是用java实现的,下面是java实现这个多线程的主要代码,用c#应该也是一样的!有兴趣的可以翻译成c#的,厚厚~
    import java.util.ArrayList;

    public class Catcher
    {
        private static ArrayList threads= new ArrayList();//存储未处理URL
        public static boolean isFinished=false;//是否已经把所有的链接存到threads了
       
        public synchronized String  getUrl()
        {
            if(threads.size()>0)
            {
                String tmp = String.valueOf(threads.get(0));
                threads.remove(0);
                return tmp;
            }else
                return null;
        }
        public void process(){
            //处理预处理
           //下面开10个线程等待处理
         new Thread(new Processer(this)).start();
         new Thread(new Processer(this)).start();
         new Thread(new Processer(this)).start();
         new Thread(new Processer(this)).start();
         new Thread(new Processer(this)).start();
         new Thread(new Processer(this)).start();
         new Thread(new Processer(this)).start();
         new Thread(new Processer(this)).start();
         new Thread(new Processer(this)).start();
         new Thread(new Processer(this)).start();

            //进入翻页的处理
            for(int j=0;j<10;j++)//从第一页翻到最后一页
            {
                for(int i = 0;i<15;i++)
                {
                    threads.add(sUrl);//把URL存进去
                }
            }
            isFinished=true;       
        }
     
       
    }

    class Processer implements Runnable
    {
        Catcher c;
        public Processer(Catcher c)
        {
            this.c = c;
        }
        public void run()
        {
            String tmp = null;
            while((tmp=c.getUrl())!=null || !c.isFinished)  //当还有记录时就处理       
            {
                if(tmp!=null)
                {
           //处理将一条信息保存到数据库
                }else//如果没标志处理则休眠一秒再重新开始处理
                {
                    try
                    {
                        Thread.sleep(1000);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
           
        }
    }

  • 相关阅读:
    [asp.net] 网页自动刷新总结
    内容页中修改母版页内容
    [asp.net] 页面传值方法小记
    [VSS2005] 源代码管理bin文件夹里的.dll总是被签出,不能同时编译解决办法
    [asp.net] 设置与获取CheckBoxList多选的值
    [转] asp.net中repeater按钮传值与分页
    [asp.net] 验证控件的属性及用法
    [asp.net] 格式化repeater字段显示
    VPS绑定中文域名方法
    M/T法测速经典解析(转)
  • 原文地址:https://www.cnblogs.com/webreport/p/872582.html
Copyright © 2011-2022 走看看