I'm using Spring ThreadPoolTaskExecutor in order to execute my threads. I want to group my threads in several groups, and that every group will have different max allowed threads.
For example, something like this:
for (MyTask myTask : myTaskList){
threadPoolTaskExecutor.setMaxThreadsForGroup(myTask.getGroupName开发者_如何学运维(), myTask.getMaxThreads());
threadPoolTaskExecutor.execute(myTask, myTask.getGroupName());
}
Somehow the threadPoolTaskExecutor should know to allow only myTask.getMaxThreads() to every group named myTask.getGroupName(), and the max threads in all tasks all together should not exceed what defined for threadPoolTaskExecutor in the applicationContext.xml
is it possible to do it in simple way?
Thanks
I can see two ways of doing this. The first (and simpler) way is to create a Map<String, ExecutorService>
which maps your group names to a specific executor with a max thread limit. This doesn't satisfy your requirement to have a max number of threads overall, but I would argue that this requirement might be an unreasonable one since you can never have total control over the number of threads running in your Java application anyway.
The second way, while more complex, gives you more control. You can have a single executor with a max pool size, and instead of submitting your jobs to it directly, you submit worker tasks which take the real tasks of a BlockingQueue
and process them until there are none left. The number of worker tasks you submit will be equal to the group thread limit. The pseudo-code might look like this:
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();
}
}
});
}
The only slight drawback with this technique is that once the worker tasks start, they won't yield until all the subtasks are complete. This might be bad if you have a fair usage policy and want to avoid starvation.
精彩评论