Будет ли количество одновременно запущенных потоков в пуле потоков фиксированного размера всегда меньше, чем corePoolSize, если очередь не заполнена?

В javadoc говорится:

Когда отправляется новая задача [...] и выполняется меньше потоков corePoolSize, создается новый поток для обработки запроса, даже если другие рабочие потоки простаивают. Если запущено больше, чем corePoolSize, но меньше, чем maximumPoolSize потоков, новый поток будет создан только в том случае, если очередь заполнена. Устанавливая одинаковые значения corePoolSize и maximumPoolSize, вы создаете пул потоков фиксированного размера. Устанавливая для maximumPoolSize практически неограниченное значение, такое как Integer.MAX_VALUE, вы позволяете пулу размещать произвольное количество одновременных задач.

Означает ли это, что количество одновременно выполняющихся потоков в пуле потоков фиксированного размера всегда будет меньше corePoolSize, если очередь не заполнена?


person Ksenia    schedule 24.02.2016    source источник
comment
Нет. Предположим, что maximumPoolSize потоки начали обрабатывать полную очередь, но новые задачи не поступают. По завершении задач вы достигнете точки, в которой corePoolSize < numberOfThreadsRunning < maximumPoolSize.   -  person bradimus    schedule 24.02.2016
comment
@bradimus, так это может произойти только после того, как очередь хотя бы раз полностью заполнится, не так ли?   -  person Ksenia    schedule 24.02.2016
comment
Я считаю, что это правильно.   -  person bradimus    schedule 24.02.2016
comment
@bradimus Здесь мы говорим о пулах фиксированного размера ... corePoolSize строго уступает maximumPoolSize по определению, что мне не хватает?   -  person GPI    schedule 24.02.2016
comment
@GPI Кто упомянул пулы фиксированного размера? В javadoc в OP специально обсуждается создание новых потоков: если запущено больше, чем corePoolSize, но меньше, чем maximumPoolSize потоков, новый поток будет создан только в том случае, если очередь заполнена. Скажите, как может быть больше corePoolSize, но меньше maximumPoolSize потоков, если corePoolSize не меньше maximumPoolSize?   -  person bradimus    schedule 24.02.2016
comment
В заголовке вопроса и в теле вопроса (часть без javadoc) явно упоминается фиксированный размер, когда я его читал. Однако в общем случае я согласен с вашим комментарием.   -  person GPI    schedule 24.02.2016
comment
Как я понял из javadocs, пул потоков фиксированного размера имеет corePoolSize = maximumPoolSize.   -  person Ksenia    schedule 24.02.2016
comment
@GPI, да, и вопрос про пул потоков фиксированного размера   -  person Ksenia    schedule 24.02.2016
comment
Итак, мой вопрос может звучать так: Означает ли это, что количество одновременно работающих потоков в пуле потоков фиксированного размера всегда будет меньше, чем corePoolSize (и maximumPoolSize, потому что corePoolSize = maximumPoolSize), если очередь не заполнена?   -  person Ksenia    schedule 24.02.2016


Ответы (1)


Означает ли это, что количество одновременно выполняющихся потоков в пуле потоков фиксированного размера всегда будет меньше, чем corePoolSize, если очередь не заполнена?

Нет.

Семантический подход

Насколько я читал, и для пулов фиксированного размера, эта цитата ничего не говорит о количестве активных потоков, конкретно относительно размера очереди. Единственное предложение, связывающее их, это одно:

Если запущено больше, чем corePoolSize, но меньше, чем maximumPoolSize потоков, новый поток будет создан только в том случае, если очередь заполнена.

Что не применяется, поскольку в пуле фиксированного размера corePoolSize равно maximumPoolSize. Условие «если» никогда не выполняется.

Однако в нем говорится:

Когда отправляется новая задача [...] и выполняется меньше потоков corePoolSize, создается новый поток для обработки запроса, даже если другие рабочие потоки простаивают.

Потоки будут создаваться до тех пор, пока не будет достигнут corePoolSize предел. Пока этот предел не достигнут, потоки не будут использоваться повторно (но они могут умереть при неперехваченном исключении или из-за тайм-аута пула). Что явно оставляет место для создания corePoolSize потоков, если мы создадим их достаточно быстро или у нас будет достаточно длинная очередь.

Экспериментальный подход

Эти знания позволяют нам представить следующий сценарий: создать фиксированный пул размером 2 с очередью ожидания размером 5, а затем отправить в пул две длительно выполняющиеся задачи. («Длительное выполнение» означает, что время выполнения каждой задачи на порядок больше, чем время, необходимое для основного потока, чтобы отправить их, и для пула потоков, чтобы подтвердить их присутствие и работать над ними). Возможный график для этого следующий:

  1. Основной поток отправляет задачу T1 в новый пустой пул.
  2. В силу приведенной выше цитаты, corePoolSize еще не достигнуто, создается новый поток для выполнения T1.
  3. Поток 1 начинает выполнение T1
  4. Основной поток отправляет T2
  5. Как и на шаге 2, создается второй поток, и пул достигает corePoolSize
  6. Как и на шаге 3, второй поток начинает выполнение задачи T2.

На данный момент пул потоков имеет пустую очередь и количество работающих потоков ровно corePoolSize, а не «меньше corePoolSize», QED.

Что это значит:

Напротив, это означает, что единственный способ получить количество потоков больше corePoolSize - это одновременное выполнение всех условий:

  1. количество запущенных потоков больше (или равно) corePoolSize, и
  2. maximumPoolSize больше, чем corePoolSize, и
  3. полная очередь
person GPI    schedule 24.02.2016
comment
на шаге 5 вы упомянули, что пул достигает corePoolSize, но мы создаем только один поток на шаге 2, и мы создали пул потоков размером 2, который не должен иметь corePoolsize ограничение на еще один поток. - person crazyStart; 24.08.2017
comment
Отправка задачи T2 на шаге 4, пока T1 все еще работает (еще не завершена), порождает второй поток, в результате чего пул достигает 2 активных потоков (corePoolSize). - person GPI; 24.08.2017