Java ForkJoin Будущее, кажется, заканчивается преждевременно - PullRequest
2 голосов
/ 09 марта 2011

Я совершенно новичок в библиотеке jsr166y, и я написал подпрограмму, использующую библиотеку forkjoin, которая разделяет запрос и одновременно запускает его для реплик базы данных.Я поместил фрагмент ниже.SelectTask расширяет RecursiveTask.

ForkJoinExecutor fjPool;
    Future queryResultsFut = null;
      for (int i = 1; i <= lastBatchNum; i++) {

...

  SelectTask selectMatchesRecursiveTask = new SelectMatchesTask(loadBalancer.getDao(), thisRuleBatch, queryResults);
  queryResultsFut = fjPool.submit(selectMatchesRecursiveTask);
}

queryResultsFut.get();

Вызов метода get предназначен для блокировки родительского потока до тех пор, пока не будут возвращены все результаты запроса, так что обработка может начатьсяпо агрегированным результатам.

Теперь, спустя некоторое время работы в среде CI, я обнаружил, что это не всегда происходит.При медленной базе данных поток будет продолжен, даже если задачи все еще выполняются.Это кажется мне противоречащим документации, которую я прочитал.

Возможно, я поступаю неправильно?Должен ли я расширить ForkJoinTask вместо RecursiveTask?

Ответы [ 3 ]

3 голосов
/ 10 марта 2011

Вы, вероятно, не должны использовать ForkJoin для этого вообще. Инфраструктура FJ специально разработана для интенсивного использования процессора неблокирующим параллелизмом задач, но вы специально используете его для блокирования задач (внешних запросов к базе данных). Я бы посоветовал вам использовать обычную среду executor для того, что вы пытаетесь сделать.

Единственный аспект FJ, который соответствует вашей проблеме - это декомпозиция задачи. Это, однако, не будет слишком сложным для ручного броска, либо простым делением n-way, либо более сложной рекурсивной стратегией.

1 голос
/ 09 марта 2011

RecursiveTask наследует его функциональность get от ForkJoinTask, поэтому расширение ForkJoinTask не будет иметь другого эффекта.Имейте в виду, что каждый раз, когда вы отправляете заявку, вы получаете другой ForkJoinTask.Сколько раз вы вызываете fjPool.submit?Если вы делаете это больше, чем один раз, вы получите последнее заданное вами задание и, таким образом, queryResultsFut выполнит (то есть вернется из get), когда завершится последнее задание.

Поскольку вы имеете дело с пулом ForkJoin,следует ожидать ForkJoinTask после отправки вместо будущего.Основное назначение платформы JF - обработка разделяй и властвуй.Это наиболее полезно, когда вы можете разбить проблему на более мелкие похожие проблемы, выполнить их параллельно, затем объединить результаты и вернуть.

0 голосов
/ 10 марта 2011

Попробуйте использовать другой метод fork-join: http://www.coopsoft.com/ar/ForkJoinArticle.html

...