【发布时间】:2020-04-22 15:19:12
【问题描述】:
我已经使用 Spring Boot @Async 在我的应用程序中实现了一个方法的异步执行。我有一个带有 20 个线程的自定义线程池。在 for 循环中调用 async 方法 30 次。
每个单独的请求都是异步执行的,但是当我从浏览器同时向我的 API 发出两个不同的请求时,第一个请求正在执行,然后是第二个请求。不是两个请求并行执行相同的方法。
我认为当第一个请求到达应用程序时,它开始执行异步方法,并且由于它正在执行 30 次并且我的池有 20 个线程,所有线程都忙于执行第一个请求。所以即使是第二个请求也因为线程池繁忙而执行,另一个请求正在等待池中的线程空闲。
我们可以为每个单独的请求设置单独的线程池吗?或者我们可以使每个请求的执行独立于其他请求处理的任何方式。
这是我的代码示例。
@SpringBootApplication
@EnableAsync
public class AppBootStrap
{
public static void main(String[] args)
{
SpringApplication.run(AppBootStrap.class, args);
}
@Bean
public AsyncTaskService asyncTaskService() {
return new AsyncTaskService();
}
@Bean(name="customExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor poolExecutor = new ThreadPoolTaskExecutor();
poolExecutor.setCorePoolSize(10);
poolExecutor.setMaxPoolSize(20);
poolExecutor.setThreadNamePrefix("customPoolExecutor");
poolExecutor.initialize();
return poolExecutor;
}
}
**Controller Class:**
@RestController
public class TaskController
{
@Autowired
private TaskService taskService;
@RequestMapping("/performAction")
public void performAction() {
taskService.performAction();
}
}
**Service class**
@Service
public class TaskService
{
@Autowired
private AsyncTaskService asyncTaskService;
public void performAction()
{
for(int i = 0; i < 30; i++) {
asyncTaskService.greetings(i);
}
}
}
**Async Method Class**
public class AsyncTaskService
{
@Async
public void greetings(Integer i)
{
try
{
Thread.sleep(500 * (i + 10));
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Welcome to Async Service: " + i);
}
}
【问题讨论】:
-
Not both requests executing the same method in parallel.这完全是错误的,在 servlet 容器中,每个请求都有自己的线程,因此所有内容都始终按照定义并行。但是如果没有剩余线程。其他请求需要等待,但每个请求总是并行执行。 -
如果你想使用你的自定义执行器,你应该在异步注释中提供它的名称
@Async("customExecutor") -
你的话完全正确。但是在这种情况下,两个差异请求到达服务器,所以执行肯定是并行的,但是当执行到这个特定的逻辑(异步方法执行)时,就会发生等待。对于异步注释,我还添加了自定义执行器。忘记在上面的代码中提及了。
-
请更新您的代码,然后使用正确的代码
标签: java multithreading spring-boot threadpoolexecutor