我有一个应用程序,它可以抓取大约六千个url。为了最大限度地减少这项工作,我创建了一个RecursiveTask,它使用了所有要抓取的URL的ConcurrentLinkedQueue。它最多可以拆分50次,如果que是空的,它会直接抓取它,但如果没有,它首先会创建一个自己的新实例并分叉,之后它会抓取50的子集,之后它将加入分叉任务。 / p>
现在出现了我的问题,直到每个线程同时处理他的50个全部四个快速工作。但是在两次停止工作并等待加入之后,只有其他两个正在工作并创建新的分支和抓取页面。
为了可视化,我计算一个线程抓取的mouch URL的数量,并让JavaFX gui显示它。
我错了所以ForkJoinFramewok只使用了我的四个允许线程中的两个?我该怎么做才能改变它?
这是我的任务计算方法:
LOG.debug(
Thread.currentThread().getId() + " Starting new Task with "
+ urlsToCrawl.size() + " left."
);
final ConcurrentLinkedQueue<D> urlsToCrawlSubset = new ConcurrentLinkedQueue<>();
for (int i = 0; i < urlsToCrawl.size() && i < config.getMaximumUrlsPerTask(); i++)
{
urlsToCrawlSubset.offer(urlsToCrawl.poll());
}
LOG.debug(
Thread.currentThread().getId() + " Crated a Subset with "
+ urlsToCrawlSubset.size() + "."
);
LOG.debug(
Thread.currentThread().getId()
+ " Now the Urls to crawl only left " + urlsToCrawl.size() + "."
);
if (urlsToCrawl.isEmpty())
{
LOG.debug(Thread.currentThread().getId() + " Crawling the subset.");
crawlPage(urlsToCrawlSubset);
}
else
{
LOG.debug(
Thread.currentThread().getId()
+ " Creating a new Task and crawling the subset."
);
final AbstractUrlTask<T, D> otherTask = createNewOwnInstance();
otherTask.fork();
crawlPage(urlsToCrawlSubset);
taskResults.addAll(otherTask.join());
}
return taskResults;
P.S。如果我允许最多80个线程,它将使用它们直到每个网站都有50个网址被抓取然后只使用两个。
如果您有兴趣,请参阅完整的源代码:https://github.com/mediathekview/MServer/tree/feature/cleanup
答案 0 :(得分:0)
我修好了它。我的错误是,我分手然后工作了一个小的protion而不是等待而不是分成两半,然后再与剩下的一半再打电话给我自己等。
换句话说,在我分开并直接工作之前,但是正确的是分裂直到所有人分开然后开始工作。
以下是我的代码现在的样子:
@Override
protected Set<T> compute()
{
if (urlsToCrawl.size() <= config.getMaximumUrlsPerTask())
{
crawlPage(urlsToCrawl);
}
else
{
final AbstractUrlTask<T, D> rightTask = createNewOwnInstance(createSubSet(urlsToCrawl));
final AbstractUrlTask<T, D> leftTask = createNewOwnInstance(urlsToCrawl);
leftTask.fork();
taskResults.addAll(rightTask.compute());
taskResults.addAll(leftTask.join());
}
return taskResults;
}
private ConcurrentLinkedQueue<D> createSubSet(final ConcurrentLinkedQueue<D> aBaseQueue)
{
final int halfSize = aBaseQueue.size() / 2;
final ConcurrentLinkedQueue<D> urlsToCrawlSubset = new ConcurrentLinkedQueue<>();
for (int i = 0; i < halfSize; i++)
{
urlsToCrawlSubset.offer(aBaseQueue.poll());
}
return urlsToCrawlSubset;
}