Я вижу два способа сделать это.Первый (и более простой) способ - создать Map<String, ExecutorService>
, который отображает имена вашей группы для конкретного исполнителя с максимальным пределом потока.Это не удовлетворяет вашему требованию иметь максимальное количество потоков в целом, но я бы сказал, что это требование может быть необоснованным, поскольку вы все равно никогда не сможете полностью контролировать количество потоков, запущенных в приложении Java.
Второй способ, хотя и более сложный, дает вам больше контроля.У вас может быть один исполнитель с максимальным размером пула, и вместо того, чтобы отправлять свои задания ему напрямую, вы отправляете рабочие задачи, которые принимают настоящие задачи BlockingQueue
и обрабатывают их, пока не останется ни одного,Количество рабочих заданий, которые вы отправите, будет равно пределу потока группы.Псевдокод может выглядеть следующим образом:
ExecutorService executor = ...
int groupThreadLimit = 3;
final BlockingQueue<Runnable> groupTaskQueue = ...;
// Add all your tasks to the groupTaskQueue.
for(int i = 0; i < groupThreadLimit; i++) {
executor.execute(new Runnable() {
public void run() {
while(true) {
Runnable r = groupTaskQueue.pollFirst();
if(r == null) {
return; // All tasks complete or being processed. Queue empty.
}
r.run();
}
}
});
}
Единственный небольшой недостаток этого метода заключается в том, что после запуска рабочих задач они не будут работать, пока не будут выполнены все подзадачи.Это может быть плохо, если у вас есть политика добросовестного использования и вы хотите избежать голодания.