- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图通过使用默认的 SimpleAsyncTaskExecutor (其中我没有显式定义任何 Executor bean)来了解 Spring Boot 中 @Async 的行为。根据 SimpleAsyncTaskExecutor 的文档,“默认情况下,并发线程数是无限的”。但在运行下面的示例代码时,我只能看到只有 8 个线程被启动,其余任务正在等待新线程来执行它们。我知道可以通过自定义执行器来防止这种情况,我可以在其中定义线程池的大小。但我想知道我对 SimpleAsyncTaskExecutor 的理解是否正确,或者我的代码有问题。
主类
@SpringBootApplication
@EnableAsync
public class MainRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(MainRunner.class);
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(MainRunner.class);
MyService myService = (MyService) applicationContext.getBean("myService");
LOGGER.info("Starting the submission of tasks...");
for (int i = 1; i <= 50; i++) {
myService.doSomething("Number" + i);
}
LOGGER.info("Finished submission of tasks...");
}
}
MyService 类
@Service
public class MyService {
private static final Logger LOGGER = LoggerFactory.getLogger(MyService.class);
@Async
public void doSomething(String userName) {
LOGGER.info(Thread.currentThread().getName() + ", "
+ Thread.currentThread().getId() + ", NAME: " + userName + " STARTING...");
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 1000000; j++) {
int res = i + j;
}
}
LOGGER.info(Thread.currentThread().getName() + ", "
+ Thread.currentThread().getId() + ", NAME: " + userName + " COMPLETE...");
}
}
我希望看到所有 50 个任务都已启动,并且它们不会等待准备好处理它们的线程。但是上面的代码导致前 8 个提交的任务开始运行,其余的任务正在等待正在运行的任务完成才能被拾取并执行。
2019-09-19 09:33:06.560 INFO 17376 --- [ main] sample.MainRunner : Starting the submission of tasks...
2019-09-19 09:33:06.564 INFO 17376 --- [ main] sample.MainRunner : Finished submission of tasks...
2019-09-19 09:33:06.566 INFO 17376 --- [ task-8] sample.MyService : task-8, 45, NAME: Number8 STARTING...
2019-09-19 09:33:06.566 INFO 17376 --- [ task-1] sample.MyService : task-1, 38, NAME: Number1 STARTING...
2019-09-19 09:33:06.566 INFO 17376 --- [ task-7] sample.MyService : task-7, 44, NAME: Number7 STARTING...
2019-09-19 09:33:06.567 INFO 17376 --- [ task-4] sample.MyService : task-4, 41, NAME: Number4 STARTING...
2019-09-19 09:33:06.566 INFO 17376 --- [ task-6] sample.MyService : task-6, 43, NAME: Number6 STARTING...
2019-09-19 09:33:06.567 INFO 17376 --- [ task-2] sample.MyService : task-2, 39, NAME: Number2 STARTING...
2019-09-19 09:33:06.567 INFO 17376 --- [ task-5] sample.MyService : task-5, 42, NAME: Number5 STARTING...
2019-09-19 09:33:06.567 INFO 17376 --- [ task-3] sample.MyService : task-3, 40, NAME: Number3 STARTING...
它等待前 8 个任务完成,然后执行剩余的任务。难道我对SimpleAsyncTaskExecutor的理解有误吗?
最佳答案
您的代码未使用 SimpleAsyncTaskExecutor。
使用@EnableAsync简单地说
Enables Spring's asynchronous method execution capability, similar to functionality found in Spring's XML namespace.
Spring 不会基于该注释创建 SimpleAsyncTaskExecutor。查看日志输出:
2019-09-19 12:45:43.475 INFO 19660 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
Spring 似乎正在创建一个默认的 ThreadPoolTaskExecutor,它可能与您计算机上的内核数量相关(不过我并没有真正检查过)。
如果您确实想要 SimpleAsyncTaskExecutor,您可以在配置中实现 AsyncConfigurer 接口(interface)
@SpringBootApplication
@EnableAsync
public class MainRunner implements AsyncConfigurer {
private static final Logger LOGGER = (Logger) LoggerFactory.getLogger(MainRunner.class);
@Override
public Executor getAsyncExecutor() {
return new SimpleAsyncTaskExecutor();
}
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(MainRunner.class);
MyService myService = (MyService) applicationContext.getBean("myService");
LOGGER.info("Starting the submission of tasks...");
for (int i = 1; i <= 50; i++)
{
myService.doSomething("Number" + i);
}
LOGGER.info("Finished submission of tasks...");
}
}
关于java - SimpleAsyncTaskExecutor 仅启动 8 个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58013472/
我正在同一 JVM 实例中运行多个 Spring Batch 分区作业。每个都配置为使用 3 个线程,但每次新作业启动时,我都会在日志中看到 SimpleAsyncTaskExecutor 不断增加其
我需要同时运行一些线程,但需要强制每个进程在新线程中运行(这是由于我无法完全控制的一些 ThreadLocal 出血)。为此,我一直在使用 SimpleAsyncTaskExecutor。然而,这样做
在我的 Spring Batch 项目中,我需要从表中读取行列表,创建 4 行的 block 并进行处理,然后写入另一个表。我已经实现了 SimpleAsyncTaskExecutor 以允许并行处理
我试图通过使用默认的 SimpleAsyncTaskExecutor (其中我没有显式定义任何 Executor bean)来了解 Spring Boot 中 @Async 的行为。根据 Simple
我正在处理一个现有的应用程序,它有这段代码 我们有一个方法,就是使用上面的 taskExecutor 来完成一个特定的任务。 (此任务应该完成,但可
在我的应用程序中,我试图对服务进行异步调用,这样我就不必等待那个昂贵的调用。我正在使用 SimpleAsyncTaskExecutor 但没有运气。请参阅下面我的代码片段。知道我错过了什么吗? 我的要
我有以下配置: 然后是下面的类 public class SomeClassImpl implements SomeClass { @Async @Ov
最初我有以下配置: @Configuration public class ParallelFlowConfig { @Autowired private JobBuilderFact
我有一个简单的 Spring Boot 应用程序,其中一个 enpoint 通过 JobLauncher bean 中配置的 SimpleAsyncTaskExecutor 异步调用 Spring B
我们在生产中有一个 Spring 应用程序,它似乎正在泄漏线程。 当我进行线程转储时,我看到以下线程似乎正在等待。下面是一个示例,但数量有数千个 "SimpleAsyncTaskExecuto
我有使用 SimpleAsyncTaskExecutor 运行的 spring 批处理作业。我必须为作业实现一个测试用例。但测试完成后Afterjob仍然执行。 在我的测试用例中,我有一个无限循环,我
我是一名优秀的程序员,十分优秀!