2

我有 10 个网络爬虫,它们共享一个LinkedBlockingQueue.

从我在 Eclipse 中的调试视图中,我发现当我获取了几个 URL(大约 1000 个)时,list.take()调用需要很长时间。

这是它的工作原理:

private (synchronized) URL getNextPage() throws CrawlerException {
    URL url;
    try {
        System.out.println(queue.size());
        url = queue.take();
    } catch (InterruptedException e) {
        throw new CrawlerException();
    }
    return url;
}

我只添加synchronized并用于调试目的,以查看列表在被调用queue.size()时是否真的被填满。take()是的,它是(这次运行中有 1350 个元素)。

queue.put()另一方面,仅当 URL 是新的时才会调用:

private void appendLinksToQueue(List<URL> links) throws CrawlerException {
    for (URL url : links) {
        try {
            if (!visited.contains(url) && !queue.contains(url)) {
                queue.put(url);
            }
        } catch (InterruptedException e) {
            throw new CrawlerException();
        }
    }
}

但是,所有其他 Crawler 似乎也不会产生太多新 URL,因此队列不应真正阻塞。这是我们在队列中有多少个 URL(以 5 秒为间隔):

Currently we have sites: 1354
Currently we have sites: 1354
Currently we have sites: 1354
Currently we have sites: 1354
Currently we have sites: 1355
Currently we have sites: 1355
Currently we have sites: 1355

根据Java doccontains()是继承自的,AbstractCollection所以我猜这至少与多线程没有任何关系,因此也不能成为阻塞的原因。

重点是,从我的调试中我还可以看到其他线程似乎也被阻止在 list.take() 中。然而,它不是一个永恒的障碍。有时,爬虫可以继续运行,但它们会卡住超过一分钟。目前,我看不到他们中的任何一个正在发生。

你知道这怎么会发生吗?

4

0 回答 0