Начать новый поток вместо помещения в очередь

Из javadoc для ThreadPoolExecutor:

Когда новая задача отправляется в методе execute (java.lang.Runnable) .... Если количество запущенных потоков больше corePoolSize, но меньше maximumPoolSize, новый поток будет создан только в том случае, если очередь заполнена.

Как я могу сделать ThreadPool, который будет запускать новый поток вместо отправки задачи в очередь в этой ситуации?

Пример:

У меня есть поток с corePoolSize = 5 и maxPoolSize = 10 и неограниченной очередью.

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

Предположим, потоки maxPoolSize сейчас заняты, и прибыла новая задача - пул должен сохранить задачу в очереди, а первый свободный поток должен взять эту задачу и выполнить.


person ice    schedule 26.09.2012    source источник
comment
При этом упускается смысл использования пула потоков в первую очередь. Пул потоков предназначен для повторного использования потока для нескольких задач. Если вы хотите запускать новый поток для каждой задачи, просто создайте новый поток самостоятельно, нет необходимости использовать пул потоков.   -  person Abhinav Sarkar    schedule 26.09.2012
comment
Весь смысл пула потоков состоит в том, чтобы повторно использовать существующие потоки, когда они простаивают. Не могли бы вы немного уточнить и объяснить, чего вы хотите достичь?   -  person assylias    schedule 26.09.2012
comment
У меня есть ограничение - максимум 100 рабочих потоков - это мой maxPoolSize. Мне нужно, чтобы каждый раз было готово какое-то количество потоков - это мой corePoolSize. И у меня неограниченная очередь. Я хочу использовать все 100 потоков, если у меня есть задачи для каждого из них.   -  person ice    schedule 26.09.2012
comment
Возможный дубликат stackoverflow.com/questions/19528304/   -  person Gray    schedule 23.10.2013


Ответы (3)


Если вам нужен пул потоков с максимальным размером, в котором задачи ставятся в очередь только тогда, когда все потоки заняты.

ExecutorService service = Executors.newFixedThreadPool(numberOfThreads);

Кэшированный пул потоков, который не будет ставить задачи в очередь, но при необходимости создаст новый поток. Он будет повторно использовать поток, если он свободен.

ExecutorService service = Executors.newCachedThreadPool();
person Peter Lawrey    schedule 26.09.2012
comment
Да, что-то вроде кешированного пула потоков, но с максимальным размером рабочих потоков. И если этот максимальный размер достигнут, задачи должны оставаться в очереди. - person ice; 26.09.2012
comment
Значит, вам все-таки нужна очередь. :) - person Peter Lawrey; 26.09.2012
comment
В fixedThreadPool все потоки либо живут вечно, либо все будут уничтожены через некоторое время. Мне нужно какое-то количество (но не все), чтобы жить вечно. - person ice; 26.09.2012
comment
Вы можете создать пул потоков, срок действия которого истекает, но обычно в этом нет необходимости, поскольку имеет значение только пиковое использование. - person Peter Lawrey; 26.09.2012

Я только что разместил этот точный вопрос и дал там ответ:

Как получить ThreadPoolExecutor, чтобы увеличить количество потоков до максимума перед постановкой в ​​очередь?

Извините, что не нашел этот вопрос заранее, иначе я бы просто ответил на него.

Подводя итог ответу, я расширяю LinkedBlockingQueue, чтобы он всегда возвращал false для queue.offer(...), что при необходимости добавит в пул дополнительные потоки. Если в пуле уже установлено максимальное количество потоков и все они заняты, будет вызван RejectedExecutionHandler. Затем обработчик помещает put(...) в очередь.

В моем ответе есть образец кода. Опять же, извините за обман.

person Gray    schedule 22.10.2013

Если вы хотите запускать новый поток каждый раз, независимо от наличия незанятых потоков, вам вообще не нужен ThreadPool - просто создайте и запустите новый поток вручную. Это лучше, потому что ваши потоки умрут сразу после того, как они сделают свою работу, а в ThreadPool они будут ждать некоторое время для нового задания, но никогда не получат его, таким образом только тратя память.

person Alexei Kaigorodov    schedule 26.09.2012