Spring async ConcurrentTaskExecutor 没有真正正常工作? [英] Spring async ConcurrentTaskExecutor not really working correctly?
问题描述
这是我第一次在 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.
- 您的组件实现了
AsyncConfigurer
- 您没有
@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
.我使用了 ThreadPoolTaskExecutor
而不是 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屋!