この作業を最小限に抑えるために、クロールするすべての URL の ConcurrentLinkedQueue を消費する RecursiveTask を作成しました。50 まで分割し、キューが空の場合は直接クロールしますが、そうでない場合は、最初にそれ自体の新しいインスタンスを作成してフォークし、その後 50 のサブセットをクロールし、その後フォークされたタスクに参加します。
ここで問題が発生します。各スレッドが 50 の作業を完了するまで、4 つすべての作業が同時に迅速に行われます。しかし、2 つが動作を停止して参加を待っていると、他の 2 つだけが動作し、新しいフォークとクローリング ページを作成しています。
これを視覚化するために、スレッドがクロールする URL の数を数え、JavaFX GUI に表示させます。
ForkJoinFramewok が許可された 4 つのスレッドのうち 2 つしか使用しないようにするには、何が問題なのですか? 変更するにはどうすればよいですか?
タスクの計算方法は次のとおりです。
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;
Ps 最大 80 のスレッドを許可する場合は、50 個の URL がクロールされてから 2 つだけが使用されるまで使用されます。
興味のある方は、完全なソース コードをご覧ください: https://github.com/mediathekview/MServer/tree/feature/cleanup
