Какой исполнитель пула потоков 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.

Другие вопросы по тегам