这个时候主要创建了4个类:Config.java、DownPage.java、GetURL.java、DownImage.java。
在Text.java类中测试的时候由于是单独测试,没有任何问题,所有功能都可以正常使用,但是当几个功能同时运行的时候就出现了问题。
由于有几个容器,DownPage.java、GetURL.java和DownImage.java三个类都要监视着各自的容器,一旦有数据,立刻开始工作,这就需要不同的线程来完成监听。每个类都至少需要一个线程来处理。
Java中实现多线程有两种方式,一种是继承Thread类,一种是实现Runnable接口。这里选用实现接口。
在上面说的三个类里面都实现Runnable接口的run()方法。
DownPage.java:
@Override public void run() { try { while(true){ while(getPage(URLFactory.URL_LIST.poll())){ Thread.sleep(200); } Thread.sleep(1000); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
GetURL.java:
@Override public void run() { try { while(true){ while(getURL(URLFactory.FILE_LIST.poll())){ Thread.sleep(100); } Thread.sleep(1000); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } }
DownImage.java:
@Override public void run() { try { while(true){ while(saveImage(URLFactory.IMAGE_LIST.poll())){ Thread.sleep(100); } Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } }
可以看到,每个run()里面都是用了双while循环,外层的循环用来在容器里没有数据的时候进行等待。内层的循环用来取出数据并处理,每次间隔200毫秒。
然后再Text.java中进行测试:
DownPage downPage = new DownPage(); Thread threadDownPage = new Thread(downPage); GetURL getURL = new GetURL(); Thread threadGetURL = new Thread(getURL); DownImage downImage = new DownImage(); Thread threadDownImage = new Thread(downImage); URLFactory.URL_LIST.put("http://catcoder.com"); threadDownPage.start(); threadGetURL.start(); threadDownImage.start();
功能正常运行!一个单线程的初步可用的爬虫程序就初步完成,就是说,嗯,能运行了,但是距离能用还是有一段距离。
下面需要进行的就是去除重复URL,去除重复图片,真正的多线程。