ForkJoinFramework仅使用两名工作人员

时间:2017-09-15 23:07:30

标签: java multithreading fork-join forkjoinpool

我有一个应用程序,它可以抓取大约六千个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;

这是我的图表的快照: enter image description here

P.S。如果我允许最多80个线程,它将使用它们直到每个网站都有50个网址被抓取然后只使用两个。

如果您有兴趣,请参阅完整的源代码:https://github.com/mediathekview/MServer/tree/feature/cleanup

1 个答案:

答案 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;
}