2013-10-04 2 views
2

Я использую ThreadPoolexecutor, заменив его на устаревший Thread.Оптимизация пула потоков Executor-java

Я создал исполнитель, как показано ниже:

pool = new ThreadPoolExecutor(coreSize, size, 0L, TimeUnit.MILLISECONDS, 
     new LinkedBlockingQueue<Runnable>(coreSize), 
     new CustomThreadFactory(name), 
     new CustomRejectionExecutionHandler()); 
pool.prestartAllCoreThreads(); 

Здесь основной размер MaxPoolSize/5. Я запустил все основные потоки при запуске приложения примерно около 160 потоков.

В устаревшем дизайне мы создавали и начинаем около 670 потоков.

Но дело даже в том, что после использования Исполнителя и создания и замены устаревшего дизайна мы не получаем гораздо лучших результатов.

Для управления памятью результатов мы используем верхнюю команду для просмотра использования памяти. В течение времени мы установили регистраторы System.currentTime в миллисекунд, чтобы проверить использование.

Пожалуйста, расскажите, как оптимизировать этот дизайн. Благодарю.

+1

Вы не дали нам много работы, чтобы работать здесь. Я бы сказал, что вам не хватает флюсового конденсатора. –

ответ

3

Но дело даже в том, что после использования Исполнителя и создания и замены устаревшего дизайна мы не получаем гораздо лучших результатов.

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

Звучит так, будто вы не блокировались из-за переключения контекста. Возможно, ваше приложение связано с IO или иным образом ожидает другого ресурса системы. Потоки 670 звучат как много, и вы бы использовали много памяти стека потоков, но в противном случае это могло бы не сдерживать производительность вашего приложения.

Обычно мы используем классы ExecutorService не обязательно, потому что они быстрее, чем сырые потоки, но поскольку код проще в управлении. Одновременные классы заботятся о большом количестве блокировок, очередей и т. Д. Из ваших рук.

Пара код комментарии:

  • Я не уверен, что вы хотите LinkedBlockingQueue быть ограничена колонкового размера. Это два разных номера. core-size - минимальное количество потоков в пуле. Размер BlockingQueue - это то, сколько заданий можно поставить в очередь, ожидая свободной нити.

  • Как и в сторону, то ThreadPoolExecutor никогда не будет выделять поток мимо основного числа потоков, еслиBlockingQueue не заполнится. В вашем случае, если все ядро-потоки заняты, а очередь заполнена количеством заданных по размеру номеров в очереди, когда следующий поток разветвляется.

  • Мне никогда не приходилось использовать pool.prestartAllCoreThreads();. Основные потоки будут запущены после того, как задачи будут отправлены в пул, поэтому я не думаю, что вы покупаете вас много - по крайней мере, не с давно запущенным приложением.

Для времени мы поместили лесоруб из системы.currentTime в миллисекундах для проверки использования.

Будьте осторожны. Слишком много регистраторов могут повлиять на производительность вашего приложения, а не на его повторное архивирование. Но я полагаю, вы добавили регистраторы после, вы не заметили улучшения производительности.

0

Исполнитель просто обертывает создание/использование Threads, поэтому он не делает ничего волшебного.

Похоже, что у вас есть узкое место в другом месте. Вы запираетесь на одном объекте? У вас есть один однопоточный ресурс, который попадает в каждый поток? В таком случае вы не увидите никаких изменений в поведении.

Является ли ваш процесс связан с процессором? Если так, ваши потоки должны (очень грубо говоря) соответствовать количеству обрабатываемых ядер. Обратите внимание: каждый создаваемый поток потребляет память для своего стека, а если вы привязаны к памяти, то создание нескольких потоков здесь не поможет.

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