有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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将继续加载更多页面。现在如何限制页面爬网限制

我的方法是:

  1. 针对每个种子URL,我维护一个计数器映射,让我知道当前处理的页面。基于此,我限制了进程调用,然后超时逻辑开始,循环退出。这里的问题是,我需要使映射线程也安全,这增加了复杂性。此外,这种方法似乎有点老套,因为我依赖于退出的重试,而不是正确的关闭
  2. 在while循环中检查的带有count threshold的信号量。我acquire()每次我提交给process()并且当它达到0时,我从循环中中断,等待处理的循环完成。这将主要作为上限停止,但我仍将依赖于下限停止的超时逻辑
  3. 使用毒药/哨兵,这将是一个上限停止。不知道如何计算下限

注意:我真的不能依靠队列为空来打破循环,因为它可能会导致竞争条件错误。此外,队列可以处理多个种子URL,而不限于一个域

请告诉我处理这种情况的最佳方式


共 (0) 个答案