Организовать потоки в группы и установить разные максимальные потоки для каждой группы - PullRequest
1 голос
/ 17 апреля 2011

Я использую Spring ThreadPoolTaskExecutor для выполнения моих потоков. Я хочу сгруппировать свои потоки в несколько групп, и чтобы каждая группа имела разные максимально допустимые потоки.

Например, что-то вроде этого:

for (MyTask myTask : myTaskList){
    threadPoolTaskExecutor.setMaxThreadsForGroup(myTask.getGroupName(), myTask.getMaxThreads());
    threadPoolTaskExecutor.execute(myTask, myTask.getGroupName());
}

Каким-то образом threadPoolTaskExecutor должен знать, чтобы разрешить только myTask.getMaxThreads () для каждой группы с именем myTask.getGroupName (), и максимальное количество потоков во всех задачах не должно превышать того, которое определено для threadPoolTaskExecutor в applicationContext.xml

возможно ли сделать это простым способом?

Спасибо

1 Ответ

1 голос
/ 18 апреля 2011

Я вижу два способа сделать это.Первый (и более простой) способ - создать 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();
            }
        }
    });
}

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

...