java如何在不知道要预先处理的项目数的情况下停止队列处理?
假设我正在以生产者/消费者模型的形式构建一个webcrawler
我的爬虫程序有一个队列,生产者将种子URL加入队列。 消费者从队列中读取内容,在页面上搜索链接,并在重复验证(使用“处理的”集合完成)后将其放入相同的队列中
我的问题是,我不知道种子URL可以有多少个页面。此外,我不想让爬虫程序无限制地运行,我想让一个threshold
的,比如说500页的爬虫全部被爬过
我的代码如下:
int retryCount = 0;
while(true){
if(!queue.empty()){
process(queue.poll()); // assume process method runs in multiple threads.
retryCount = 0; // reset the retry count
}else{
Thread.sleep(1000) // wait for 1 second before retrying.
if(retryCount == threshold){
break;
}
retryCount++;
}
}
案例1:如果我的种子URL有5个页面,那么这5个页面将被爬网,并且在某一点上,队列将变为空,这将在退出while循环之前启动重试逻辑。这也有助于我在爬行ie中防止任何网络延迟。它就像超时一样
案例2:如果我的种子URL有更多页面,比如100,那么我的队列将加载100,inturn将继续加载更多页面。现在如何限制页面爬网限制
我的方法是:
- 针对每个种子URL,我维护一个计数器映射,让我知道当前处理的页面。基于此,我限制了进程调用,然后超时逻辑开始,循环退出。这里的问题是,我需要使映射线程也安全,这增加了复杂性。此外,这种方法似乎有点老套,因为我依赖于退出的重试,而不是正确的关闭李>
- 在while循环中检查的带有count
threshold
的信号量。我acquire()
每次我提交给process()
并且当它达到0时,我从循环中中断,等待处理的循环完成。这将主要作为上限停止,但我仍将依赖于下限停止的超时逻辑李> - 使用毒药/哨兵,这将是一个上限停止。不知道如何计算下限李>
注意:我真的不能依靠队列为空来打破循环,因为它可能会导致竞争条件错误。此外,队列可以处理多个种子URL,而不限于一个域
请告诉我处理这种情况的最佳方式
共 (0) 个答案