Какой исполнитель пула потоков Java использовать, чтобы легко изменить размер пула?
Мне нужно выполнить большое количество краткосрочных задач. я использую ThreadPoolTaskExecutor
для этого, но мне нужно изменить минимальный / максимальный размер пула потоков автоматически во время выполнения. Как это сделать?
Сейчас я использую внешнюю переменную AtomicInteger и увеличиваю ее перед отправкой и уменьшаю в лямбда-обратном вызове. Могу ли я пропустить это как-нибудь? Просто используйте executor пула потоков и больше ничего?
Я прочитал много статей, и люди не рекомендуют делать это, мое решение хорошо или я могу упростить его? Я использую весну, может быть, я могу использовать что-то оттуда?
3 ответа
Из API-документа ThreadPoolExecutor:
(...) Чаще всего размер ядра и максимальный пул устанавливаются только при создании, но они также могут динамически изменяться с помощью setCorePoolSize(int) и setMaximumPoolSize(int).
Поэтому, если действительно необходимо изменить эти параметры во время выполнения, создайте ThreadPoolExecutor
и настроить его по мере необходимости.
Но прежде чем подумать дважды, нужен ли вам динамический пул потоков. Обычно, если ваши задачи не связаны с какими-либо другими ресурсами, кроме ЦП, невыгодно иметь гораздо больше потоков, чем процессоров.
Так почему бы не использовать Runtime.getRuntime().availableProcessors()
как приблизительное значение?
Теперь я думаю, что понимаю вашу проблему лучше. Учитывая это описание, я думаю, что наличие одного ThreadPoolExecutor на одного работника является хорошим подходом:
// Worker 1 //
int w1ThPoSize = 5; // Initially 5 threads are assigned to worker 1
ThreadPoolExecutor w1ThPo =
new ThreadPoolExecutor(w1ThPoSize,
w1ThPoSize,
0, // No excess threads, so keep alive time is not relevant
TimeUnit.MILLISECONDS, // keep alive time is 0, so no relevant
new LinkedBlockingQueue<Runnable>());
// Sending a task for worker 1
w1ThPo.execute(() -> { System.out.println("I'm running"); });
// Resizing worker 1 thread pool
w1ThPoSize = 10;
w1ThPo.setCorePoolSize(w1ThPoSize);
w1ThPo.setMaximumPoolSize(w1ThPoSize);
// (similar approach for remaining workers)
// When done, remember to shutdown thread pools!
w1ThPo.shutdown();
Если я понял, вы просите пул создать новый поток (увеличить размер пула) при запуске задачи и попросить его закрыть поток (уменьшить размер пула) после завершения задачи - пожалуйста, исправьте меня, если я неправильно понял вас!
Это то, что вы делаете, я хотел бы отказаться от этого подхода и просто "пусть пул будет". Создание потоков не из дешевых, и я предполагаю, что ваша задача может использовать одни и те же потоки снова и снова (для этого нужны пулы). Хороший подход состоит в том, чтобы установить количество потоков равным количеству процессоров, как предлагает isnot2bad.