Reputation: 71
Below is my configuration on the threadpool
<bean id="executorServiceThreadPool"
class="org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean">
<property name="corePoolSize" value="100" />
<property name="maxPoolSize" value="500" />
<property name="keepAliveSeconds" value="60" />
<property name="WaitForTasksToCompleteOnShutdown" value="true" />
</bean>
and i am creating threads in a for loop and executing them all together.
for(int i=0;i<sublist.size();i++) {
Callable<Object> secDataTask = createTask(businessDate, sublist.get(i));
taskList.put(SecYieldConstants.SECURITY_SEC_TASK+i, secDataTask);
}
Map<Callable<Object>,Object> taskResult =
commonTaskExecutor.executeTasksConcurrently(MAX_TIMEOUT, taskList);
the list is typically 10-20K, and for each item in list there are about 10 tasks getting created.
when i execute it with default setting, i either get InterruptedException or get IndexOutOfBoundException.
however if i create a sublist of only 5-10 it works fine,
what should my pool size be in this situation? or is there a way i can let JVM handle my pool size
Code for creating tasks:
private Callable<Object> createTask(final Date businessDate,final Object obj) {
Callable<Object> securitySecTask = new Callable<Object>() {
public Object call() throws Exception {
Object result = retrieveInnerResult(businessDate,obj)
return result;
}
};
return securitySecTask;
}
private Callable<Object> retrieveInnerResult(final Date businessDate,final Object obj) {
Callable<Object> securitySecTask = new Callable<Object>() {
public Object call() throws Exception {
Object result = retrievetask2Result(businessDate,obj)
return result;
}
};
return securitySecTask;
}
Upvotes: 1
Views: 240
Reputation: 71
The task gets executed without any issues if i add only fewer tasks to the tasklist. Here is the code i am using.
/**
* @param timeout
* @param Map<String,Callable<Object>> taskExecutionList
* @return Map<Callable<Object>, Object>
* @throws Exception
*/
public Map<Callable<Object>, Object> executeTasks(Long timeout, Map<String, Callable<Object>> taskExecutionList) throws Exception{
//Execute all valid tasks and await termination (all tasks to be complete or timeout as passed by caller)
List<Future<Object>> taskResult = executorServiceThreadPool.invokeAll(taskExecutionList.values(), timeout, TimeUnit.SECONDS);
return retrieveTaskResult(taskExecutionList, taskResult);
}
/**
* @param taskset
* @param executedTasks
* @return Map<Callable<Object>, Object>
* @throws Exception
*/
private Map<Callable<Object>, Object> retrieveTaskResult(Map<String,Callable<Object>> taskset, List<Future<Object>> executedTasks) throws Exception {
Map<Callable<Object>, Object> result = new LinkedHashMap<Callable<Object>, Object>();
int taskCount = 0;
//populate result map with callable and respective results from Future
for(Map.Entry<String, Callable<Object>> task : taskset.entrySet()){
Callable<Object> callableTask = task.getValue();
Future<Object> taskResult = executedTasks.get(taskCount);
if(!taskResult.isCancelled() && taskResult.isDone()){
result.put(callableTask, taskResult.get());
}
taskCount++;
}
return result;
}
Upvotes: 0
Reputation: 53819
The IndexOutOfBoundException
error probably comes from adding an element to taskList
at a specific index (or somewhere else in the code!) and has nothing to do with the thread pool.
Regarding the thread pool, 100 as a core size is big and 500 as a max is very big! Most likely the code is running on a cpu that does not have that many cores. So unless the code being executed is heavily blocking (like waiting for web queries), having that many threads is probably slowing down the overall execution. Try reducing the number of threads to see how the program reacts.
Regarding the InterruptedException
, it may be that you are trying to shutdown the pool and that some tasks are being executed that can be interrupted and that throw that exception. Hard to tell without more information.
I hope this helps.
Upvotes: 1