2015-11-26 2 views
0

Я использую Fork/Join Framework для выполнения большого количества вычислений параллельно. Я реализовал шаблон производителя и потребителя с помощью простого регистратора для создания консольных выходов, когда программа вычисляет. Производитель и потребитель делят BlockingQueue, и я использую метод put(), поэтому я не пропущу обновления.BlockingQueue's put() и высокий уровень параллелизма

Я признал, что производительность при некоторых обстоятельствах ужасна, и VisualVM показал мне, что причиной является метод put().

Когда есть проблема ввода новых сообщений в BlockingQueue моих RecursiveTask с должны ждать, но ForkJoinPool продолжает раскошелиться новые задачи, чтобы 2000-5000 задачи пытаются получить доступ к put() метод, который приводит к очень высоким параллелизмом.

Есть ли подходящий способ справиться с такими ситуациями?

Я думал, что-то вроде

if(!blockingQueue.offer(message) { 
    blockingQueue.put(message); 
} 

может быть более производительным при использовании теоретически неограниченное BlockingQueue.

Так что мой вопрос: есть ли правильный и эффективный способ поместить объекты в BlockingQueue без потери обновления?

Спасибо заранее!

+0

Несомненно, предложение-то-то-то вроде того, как положить? –

+0

Добавьте достаточно кода, чтобы мы могли видеть проблему. Как именно вы используете F/J? и т. д. – edharned

+0

@ AndyTurner Это? Итак, упомянутый фрагмент не имеет смысла? – r3r57

ответ

2

Если ваш пул нерестовал 2000-5000 заданий, то это ваша проблема. После того, как многие задачи уйдут, вы начнете рассматривать конфликт потоков в BlocingQueue.put, который будет увеличивать статистику по put.

Весь смысл использования BlockingQueue так, что если потребитель медленнее (даже временно), чем производитель тогда производитель будет блок пока потребитель не догнал. Это должно привести к тому, что процессы восходящего потока также будут ждать. Если это вызывает ваш восходящий процесс (предположительно FJP), чтобы заправить систему, а не просто блокировать, то это будет проблемой.

Я предлагаю вам использовать FJP с фиксированной емкостью.

+0

В большинстве случаев 'getActiveThreadCount()' возвращает 3-5 во время работы, но когда одна задача, которая, похоже, застревает в методе 'put()', getActiveThreadCount() 'будет поднимать до ~ 3500 и снова падать. [После вашего редактирования] Это звучит правильно для меня. Поэтому я попытаюсь использовать FJP с фиксированной емкостью, как вы предложили, и протестировать его снова. Спасибо! – r3r57

Смежные вопросы