Spring async ConcurrentTaskExecutor不能正常工作吗?

时间:2019-06-04 03:37:27

标签: spring spring-boot

这是我第一次在Spring启动中使用Async。这是我的项目的结构。

我有以下ExecutorConfig

@Configuration
@EnableAsync
public class ExecutorConfig {
    @Bean(name = "ConcurrentTaskExecutor")
    public Executor getAsyncExecutor() {
        return new ConcurrentTaskExecutor(Executors.newFixedThreadPool(10));
    }
}

下面的类,将通过@Scheduled调用

@Component
public class RealtyTracCountyScraper {

    @Autowired
    StateScrapeQueueRepository stateScrapeQueueRepository;

    @Autowired
    CountyScrapeRepository countyScrapeRepository;

    @Autowired
    CountyScraper countyScraper;

    // @Scheduled(cron = "0 0 */3 * * *")
    @EventListener(ApplicationReadyEvent.class)
    public void scrapeCountyLinks() {
        System.out.println("Scrape county links ran!");
        try {
            List<String> stateLinks = stateScrapeQueueRepository.getStatesLinks("");

            for (int i = 0; i < stateLinks.size(); i++) {
                countyScraper.run(stateLinks.get(i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("---------------------");
        }
    }

}

以及从上面的类中调用的该类(这是包含多线程方法的类)

@Component
public class CountyScraper implements AsyncConfigurer {

    @Autowired
    StateScrapeQueueRepository stateScrapeQueueRepository;

    @Autowired
    CountyScrapeRepository countyScrapeRepository;

    @Async("ConcurrentTaskExecutor")
    public void run(String stateLink) {
        System.out.println("New thread");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Done");

    }
}

即使我在ExecutorConfig类中设置了10个固定线程,看起来一次只能工作一个线程。知道我在做什么错吗?

1 个答案:

答案 0 :(得分:3)

我想您的代码中有些事情并不完全正确。

  1. 您的组件实现AsyncConfigurer
  2. 您没有@EnableScheduling

您的CountyScraper实现了AsyncConfigurer接口。导致2个可能的问题。首先是使用基于接口的代理而不是基于类的代理的默认值和用法来配置异步处理。因此,消除了@Async。尽管后者似乎并非如此,但人们可能永远不知道。

AsyncConfigurer实际上应该由您的ExecutorConfig实现。

@Configuration
@EnableAsync
@EnableScheduling
public class ExecutorConfig implements AsyncConfigurer {

    public Executor getAsyncExecutor() {
        return taskExecutor();
    }

    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new TaskExecutor();
        taskExecutor.setCorePoolSize(10);
        return taskExecutor;
    }
}

这将配置用于异步处理的默认Executor。我使用ConcurrentTaskExecutor代替了ThreadPoolTaskExecutor。后者允许进行更多配置,并在Spring Boot关闭时很好地清理线程。

提示::如果您使用的是Spring Boot 2.1,则实际上可以放弃TaskExecutor的配置,仅将其替换为配置。

现在,您可以使用简单的@Async而不是显式命名执行程序(由于名称不同,现在将失败)。

spring.task.execution.pool.core-size=10 # Default is 8

您的配置将变为

@Configuration
@EnableAsync
@EnableScheduling
public class ExecutorConfig {}