我正在尝试编写一个多线程的Web爬虫.
我的主要入门类有以下代码:
ExecutorService exec = Executors.newFixedThreadPool(numberOfCrawlers); while(true){ URL url = frontier.get(); if(url == null) return; exec.execute(new URLCrawler(this, url)); }
URLCrawler获取指定的URL,解析HTML从中提取链接,并将看不见的链接安排回边界.
边界是未抓取的URL队列.问题是如何编写get()方法.如果队列为空,则应等待任何URLCrawlers完成,然后再次尝试.仅当队列为空且当前没有活动的URLCrawler时,它才应返回null.
我的第一个想法是使用AtomicInteger来计算当前工作URLCrawler的数量以及notifyAll()/ wait()调用的辅助对象.开始时每个爬虫都会增加当前工作URLCrawler的数量,并在退出时递减它,并通知对象它已完成.
但我读到notify()/ notifyAll()和wait()是一些不赞成做线程通信的方法.
我应该在这个工作模式中使用什么?它类似于M生产者和N个消费者,问题是如何处理生产者的匮乏.