使用基于注释的SpringBoot ThreadPoolTask​​Executor时如何防止队列重载?

时间:2017-08-25 02:30:18

标签: multithreading spring-boot

我有一个基于注释的spring boot应用程序,它完成了大量数据处理并将结果存储在数据库中,我希望这是多线程的,以提高速度。

我的问题是,一旦工作队列完全填满并再次调用异步方法,我就会得到一个由TaskRejectedException引起的RejectedExecutionException。此时,当前排队的任务确实完成,但其他任务不再排队。要处理的数据量非常大,因此我无法删除队列容量的限制,因为应用程序将耗尽可用内存。

如果任务队列达到极限,我希望能够在给定的时间后退出并重试,并且我需要有关如何执行此操作的帮助。我在下面描述了我当前的设置。

在我的Application类中启用了异步,我正在使用注释创建TaskExecutor

@SpringBootApplication
@ComponentScan(basePackages = "com")
@EnableAsync
public class Application extends SpringBootServletInitializer {

...

@Bean
@Qualifier("parallelExecutor")
public TaskExecutor parallelExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(2);
    executor.setMaxPoolSize(4);
    executor.setQueueCapacity(10);
    executor.setThreadNamePrefix("Parallel Executor");
    return executor;
}

我使用@Async注释将我的数据处理和数据库存储方法声明为异步并且是多线程的。

@Async("parallelExecutor")
public void processAndStoreData(JsonObject item);

我在一个调用异步方法的单独类中循环遍历所有要处理的数据。

for (int j = 0; j < items.size(); i++) {
    // Each JsonObject
    dataStoreService.processAndStoreData(items.get(j).getAsJsonObject());
}

1 个答案:

答案 0 :(得分:0)

您是否启用了春季启动异步?也许你应该添加TaskExecutorConfig。你可以尝试

@Configuration
@EnableAsync
public class TaskExecutorConfig implements AsyncConfigurer {

    //重写getAsyncExcutor方法,并返回一个基于线程池的TaskExecutor
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(2);
    executor.setMaxPoolSize(4);
    executor.setQueueCapacity(10);
    executor.setThreadNamePrefix("Parallel Executor");
    return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}