У меня есть программа, которая порождает потоки (~ 5-150), которые выполняют кучу задач. Первоначально я использовал a, FixedThreadPool
потому что этот аналогичный вопрос предполагал, что они лучше подходят для более длительных задач, и с моими очень ограниченными знаниями о многопоточности я считал средний срок службы потоков (несколько минут) « долгоживущим ».
Однако недавно я добавил возможность создавать дополнительные потоки, и при этом я превысил установленный мной предел потоков. В этом случае было бы лучше угадать и увеличить количество потоков, которое я могу разрешить, или переключиться на a, CachedThreadPool
чтобы у меня не было потраченных впустую потоков?
Предварительно попробовав их обоих, похоже , нет никакой разницы, поэтому я склоняюсь к тому, чтобы CachedThreadPool
просто избежать потерь. Однако означает ли срок жизни потоков, что я должен вместо этого выбрать FixedThreadPool
и просто обработать неиспользуемые потоки? Из-за этого вопроса кажется, что лишние потоки не потрачены впустую, но я был бы признателен за разъяснения.
ThreadPoolExecutor
подобноеThreadPoolExecutor(0, maximumPoolSize, 60L, TimeUnit.SECONDS, SynchronousQueue())
?Оба
FixedThreadPool
иCachedThreadPool
- зло в сильно загруженных приложениях.CachedThreadPool
опаснее чемFixedThreadPool
Если ваше приложение сильно загружено и требует низкой задержки, лучше избавиться от обоих вариантов из-за следующих недостатков
CachedThreadPool
к выходу из-под контроля при создании потокаПоскольку вы знаете, что оба являются злом, меньшее зло не приносит пользы. Предпочитайте ThreadPoolExecutor , который обеспечивает детальный контроль над многими параметрами.
beforeExecute(Thread, Runnable)
иafterExecute(Runnable, Throwable)
источник
Вы уверены, что понимаете, как потоки на самом деле обрабатываются вашей ОС и выбранным оборудованием? Как Java сопоставляет потоки с потоками ОС, как это сопоставляет потоки с потоками процессора и т. Д.? Я спрашиваю, потому что создание 150 потоков внутри ОДНОЙ JRE имеет смысл только в том случае, если у вас есть массивные ядра / потоки ЦП под ними, что, скорее всего, не так. В зависимости от используемой ОС и ОЗУ создание более n потоков может даже привести к завершению работы JRE из-за ошибок OOM. Таким образом, вы должны действительно различать потоки и работу, которую они должны выполнять, сколько работы вы даже можете обработать и т. Д.
И в этом проблема с CachedThreadPool: нет смысла ставить в очередь длительную работу в потоках, которые на самом деле не могут выполняться, потому что у вас есть только 2 ядра ЦП, способные обрабатывать эти потоки. Если у вас останется 150 запланированных потоков, вы можете создать много ненужных накладных расходов для планировщиков, используемых в Java и ОС для их одновременной обработки. Это просто невозможно, если у вас всего 2 ядра ЦП, если только ваши потоки не ждут ввода-вывода или чего-то подобного все время. Но даже в этом случае множество потоков создаст много операций ввода-вывода ...
И эта проблема не возникает с FixedThreadPool, созданным, например, с помощью 2 + n потоков, где n, конечно, разумно низкое, потому что с этим оборудованием и ресурсами ОС используются гораздо меньше накладных расходов для управления потоками, которые все равно не могут выполняться.
источник