С ThreadPoolExecutor, в чем разница между allowCoreThreadTimeOut и потоками с нулевым ядром? - PullRequest
2 голосов
/ 27 апреля 2019

Читая документацию по ThreadPoolExecutor , я запутался, в чем разница между приведенным ниже примером использования:

Ноль основных потоков и десять максимальных потоков, из которых последнийвремя ожидания через 2 секунды:

ThreadPoolExecutor executor = new ThreadPoolExecutor(
        0, // core threads
        10, // max threads
        2000, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>(),
        Executors.defaultThreadFactory()
);

Десять основных потоков и десять максимальных потоков, которые оба истекают через 2 секунды:

ThreadPoolExecutor executor = new ThreadPoolExecutor(
        10, // core threads
        10, // max threads
        2000, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>(),
        Executors.defaultThreadFactory()
);

executor.allowCoreThreadTimeOut(true);

Эти исполнители ведут себя по-разному в любом случае?

1 Ответ

2 голосов
/ 27 апреля 2019

Вы можете прочитать мотивацию здесь .

Я хочу что-то вроде фиксированного пула потоков (Executors.newFixedThreadPool ()), но потоки отмирают, когда они простаивают слишкомдолго и воссоздается, когда они снова нужны.

Наиболее интуитивно понятный подход - установить размер ядра в 0, максимальный размер пула в качестве ограничивающего значения и очередь в [неограниченную очередь] - завершается неудачей: никакие задачи не выполняются вообще (в соответствии с Javadoc, но - IMHO- немного нелогично).

executor.allowCoreThreadTimeOut(true); может использоваться для получения этого поведения.

Подробнее, почему никакие задачи вообще не выполняются, если corePoolSize = 0

Из Javadoc,

Использование неограниченной очереди (например, LinkedBlockingQueue без предопределенной емкости) приведет к тому, что новые задачи будут ждать в очереди, когда все потоки corePoolSizeзаняты.Таким образом, никогда не будет создано больше, чем corePoolSize.(И поэтому значение MaximumPoolSize не имеет никакого эффекта.)

Следовательно, если вы укажете corePoolSize = 0, потоки никогда не будут созданы, и никакие задачи не будут выполнены вообще.

Однако на практике , когда corePoolSize равен нулю, реализации создают один поток (протестировано с Sun JDK6 и OpenJDK11).Таким образом, на практике задачи выполняются , но никогда не создается более одного потока, независимо от того, что указано maximumPoolSize.Я не совсем уверен, почему, потому что согласно спецификации, он не должен создавать даже один.

Ниже приведен мой тестовый код.При этом будет использоваться только один поток, но если вы укажете corePoolSize=10, он будет использовать 10. Если вы добавите allowCoreThreadTimeOut(true), то эти потоки могут прерваться.

...