ThreadPoolExecutor大小和管理线程

时间:2016-08-09 17:14:37

标签: java multithreading

以下是我在线程池上的配置

<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>

我正在for循环中创建线程并一起执行它们。

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);

列表通常为10-20K,对于列表中的每个项目,大约有10个任务被创建。

当我使用默认设置执行它时,我要么得到InterruptedException,要么得到IndexOutOfBoundException。

但是,如果我创建一个只有5-10的子列表,它可以正常工作,

在这种情况下我的游泳池大小应该是多少? 或者有没有办法让JVM处理我的池大小

创建任务的代码:

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;
    }

2 个答案:

答案 0 :(得分:1)

reservationlist.add( reservation.initialDate, reservation.finalDate, reservation.name, reservation.drivingLicenceID) ); // there is an error 错误可能来自于在特定索引处(或代码中的其他位置)向IndexOutOfBoundException添加元素,并且与线程池无关。

关于线程池,100作为核心大小是大而500作为最大是非常大!很可能代码是在没有那么多内核的cpu上运行的。因此,除非正在执行的代码严重阻塞(如等待Web查询),否则拥有那么多线程可能会降低整体执行速度。尝试减少线程数以查看程序的反应。

关于taskList,可能是您正在尝试关闭池,并且正在执行某些可能被中断并抛出该异常的任务。没有更多信息很难说。

我希望这会有所帮助。

答案 1 :(得分:0)

如果我只向任务列表添加较少的任务,则任务执行没有任何问题。 这是我正在使用的代码。

/**
     * @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;
    }