IO / связанное с сетью Fork / Join-Tasks - PullRequest
3 голосов
/ 31 января 2012

Я использую неограниченный кеширующий поток Java-ExecutorService, который одновременно обрабатывает мои задачи.Теперь у меня есть некоторые задачи, которые выполняют только некоторые длительные операции (меньшинство) и некоторые задачи, которые блокируют IO (подключение к URL-адресу, большинство).Если мое приложение запускается и запускается одна рабочая нагрузка, то около 70 задач отправляются исполнителю, который запускает 70 потоков и одновременно обрабатывает все из них.

Я хочу ограничить количество потоков на хост, к которым задача хочет подключитьсяи, если возможно, также количество общих задач.Моя проблема заключается в том, что все задачи выполняют что-то вроде fork-join, поэтому они порождают другие задачи и ждут своего результата, прежде чем продолжить.Это означает, что я не могу просто использовать семафор или ограниченную очередь для каждого хоста, поскольку задачи могут выполнять ветвление других задач, которые не будут обрабатываться, пока у семафора / очереди не будет свободного слота, поэтому приложение заблокировано.

Есть ли какой-нибудь шаблон для решения этой проблемы?

Уточнено : отправлены задачи, связанные с IO (= сетью).После выполнения некоторой работы ввода-вывода они потенциально разветвляют другие задачи, связанные с вводом-выводом, затем присоединяются к ним и, возможно, выполняют дополнительную обработку, связанную с вводом-выводом.

Кажется, что это Fork / Join с задачами, связанными с вводом-выводом.Как ограничить / ограничить выполнение задач, выполняющих ввод-вывод, без взаимной блокировки потока, который изначально разветвлял задачи (заблокирован, поскольку его разветвленные дочерние задачи не будут обработаны из-за ограничений / регулирования)?

Спасибогроздь

Ответы [ 3 ]

2 голосов
/ 01 февраля 2012

К сожалению, я не думаю, что ваша проблема вообще разрешима. Если я правильно понимаю, вы хотите отправить некоторые задачи в пул потоков, число потоков которого ограничено , верно? затем каждая задача может блокироваться для ввода-вывода, отправлять некоторые дополнительные задачи и блокировать снова, чтобы присоединиться к ним , верно?

Ну, я боюсь, что в этих условиях тупик неизбежен. Все потоки пула потоков могут быть заняты блокировкой в ​​какой-то задаче, которая ожидает запуска «разветвленной» задачи, но, конечно, не может, потому что пул исчерпан. Нет другого пути, кроме как создать больше потоков (неограниченный пул).

То, что вы могли бы сделать, это немного ограничить количество заявок во время запуска (немного поспать между каждым из них, переданным в пул).

2 голосов
/ 02 февраля 2012

Async - определенно лучший способ, так как они очень хорошо сочетаются.В то время как модель программирования в Java болезненна, использование Finagle поверх Netty является легким делом со Scala, где все операции в основном являются функцией, которая принимает запрос и возвращает Future [Response], который может быть отображен (преобразуется).

См. также:

2 голосов
/ 31 января 2012

Почему вы не используете библиотеку актеров Scala? Там вы также можете ограничить размер пула потоков, если вы хотите использовать пулы. Попробуй это: Как назначить пул потоков для актеров .

...