Создание динамического (растущего / уменьшающегося) пула потоков
Мне нужно реализовать пул потоков в Java (java.util.concurrent), чье число потоков в неактивном состоянии равно минимальному значению, увеличивается до верхней границы (но никогда больше), когда задания передаются в него быстрее, чем они заканчивают выполняться и сжимается к нижней границе, когда все задания выполнены и больше не отправляются.
Как бы вы реализовали что-то подобное? Я полагаю, что это будет довольно распространенный сценарий использования, но, очевидно,java.util.concurrent.Executors
фабричные методы могут создавать пулы фиксированного размера и пулы, которые неограниченно растут при отправке большого количества заданий.ThreadPoolExecutor
класс обеспечиваетcorePoolSize
а такжеmaximumPoolSize
параметры, но его документация, кажется, подразумевает, что единственный способ когда-либо иметь больше, чемcorePoolSize
В то же время потоки должны использовать ограниченную очередь заданий, и в этом случае, если вы достиглиmaximumPoolSize
темы, вы получите отказ в приеме на работу, с которым вам придется иметь дело? Я придумал это:
//pool creation
ExecutorService pool = new ThreadPoolExecutor(minSize, maxSize, 500, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(minSize));
...
//submitting jobs
for (Runnable job : ...) {
while (true) {
try {
pool.submit(job);
System.out.println("Job " + job + ": submitted");
break;
} catch (RejectedExecutionException e) {
// maxSize jobs executing concurrently atm.; re-submit new job after short wait
System.out.println("Job " + job + ": rejected...");
try {
Thread.sleep(300);
} catch (InterruptedException e1) {
}
}
}
}
Я что-то пропускаю? Есть лучший способ сделать это? Кроме того, в зависимости от одного из требований, может быть проблематично, что приведенный выше код не будет завершен, по крайней мере, до (я думаю)(total number of jobs) - maxSize
Работа завершена. Поэтому, если вы хотите иметь возможность отправлять произвольное количество заданий в пул и немедленно приступить к работе, не дожидаясь завершения какого-либо из них, я не вижу, как вы могли бы сделать это, не имея выделенного & quot; задания, передающего & quot; поток, управляющий необходимой неограниченной очередью для хранения всех отправленных заданий. AFAICS, если вы используете неограниченную очередь для самого ThreadPoolExecutor, его число потоков никогда не будет превышать corePoolSize.