Spring async ConcurrentTaskExecutor 没有真正正常工作? [英] Spring async ConcurrentTaskExecutor not really working correctly?

查看:28
本文介绍了Spring async ConcurrentTaskExecutor 没有真正正常工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次在 Spring Boot 中使用 Async.这是我的项目的结构.

It's my first time working with Async in Spring boot. Here is how my project is structured.

我有以下 ExecutorConfig

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

以下类将使用@Scheduled 调用

This following class which will be called with @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("---------------------");
        }
    }

}

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

and this class which gets called from the class above (This is the class that contains the multithreaded method)

@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 个固定线程,但看起来一次只有一个线程在工作.知道我做错了什么吗?

Even though I have set 10 fixed threads in the ExecutorConfig class, it looks like only one thread works at a time. Any idea what I am doing wrong?

推荐答案

我想您的代码中有些地方并不完全正确.

I guess there are a couple of things not completely right in your code.

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

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

Your CountyScraper implements the AsyncConfigurer interface. Leading to 2 possible problems. The first is configuring async processing with the defaults and usage of interface based proxies instead of class based proxies. Hence eliminating the @Async. Although the latter doesn't seem to be the case, one might never know.

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

The AsyncConfigurer should actually be implemented by your 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.我使用了 ThreadPoolTask​​Executor 而不是 ConcurrentTaskExecutor.后者允许更多的配置,并且会在 Spring Boot 关闭时很好地清理线程.

This will configure the default Executor used for async processing. Instead of a ConcurrentTaskExecutor I used the ThreadPoolTaskExecutor instead. The latter allows a bit more configuration and will cleanup the threads nicely when Spring Boot shutsdown.

提示:如果您使用的是 Spring Boot 2.1,您实际上可以放弃 TaskExecutor 的配置并仅用配置替换它.

TIP: If you are using Spring Boot 2.1 you can actually ditch the configuration of the TaskExecutor and replace it with configuration only.

现在您可以使用简单的 @Async 而不是显式命名执行器(现在会失败,因为它的命名不同).

Now you can use a simple @Async instead of naming the executor explicitly (which will now fail because it is named differently).

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

你的配置就变成了

@Configuration
@EnableAsync
@EnableScheduling
public class ExecutorConfig {}

这篇关于Spring async ConcurrentTaskExecutor 没有真正正常工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆