我有一个春季启动项目。我试图异步调用一些方法。我遵循了这个文档:https://spring.io/guides/gs/async-method/。在Application.java
中,我添加了以下方法:
@Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Rules-");
executor.initialize();
return executor;
}
请注意我已将池大小设置为2.但是当我调用异步方法5次时,会使用不同的ThreadNamePrefix创建五个不同的线程。
2017-12-01 19:16:00.901 INFO 32000 --- [cTaskExecutor-5] hello world
2017-12-01 19:16:00.930 INFO 32000 --- [cTaskExecutor-4] hello world
2017-12-01 19:16:01.372 INFO 32000 --- [cTaskExecutor-1] hello world
2017-12-01 19:16:01.376 INFO 32000 --- [cTaskExecutor-2] hello world
2017-12-01 19:16:01.985 INFO 32000 --- [cTaskExecutor-3] hello world
我不确定它的配置位置。有人可以帮忙吗?
更新
以下是我提交任务的代码:
@Component
public class MyClass {
@Autowired
private Async2 async;
public void someMethod()
{
try {
async.anotherMethod(1);
async.anotherMethod(2);
async.anotherMethod(3);
async.anotherMethod(4);
async.anotherMethod(5);
} catch(Exception e) {
e.printStackTrace();
}
}
}
@Service
public class Async2 {
private static final Logger LOGGER = Logger.getLogger(Async2.class);
@Async
public CompletableFuture<Void> anotherMethod(int i) {
LOGGER.info("hello world");
return CompletableFuture.completedFuture(null);
}
}
UPDATE2
@Controller
@RequestMapping("/a")
public class WebController {
@Autowired
private MyClass c;
@RequestMapping(value="/b", method =RequestMethod.POST)
@ResponseBody Response getResponseForRequest(@RequestBody Request request)
{
c.someMethod();
return new Response();
}
}
答案 0 :(得分:1)
似乎未加载具有自定义asyncExecutor
的配置类。检查它是否被Spring扫描并且存在@EnableAsync
注释。同样在您的示例中,anotherMethod
不会返回CompletableFuture
。
这是最小的工作样本:
@SpringBootApplication
@EnableAsync
@RestController
public class AsyncApp {
@Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Rules-");
executor.initialize();
return executor;
}
@Service
public class AsyncService {
@Async
public CompletableFuture<Void> async() {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
}
System.out.println("Hello from " + Thread.currentThread().getName());
return CompletableFuture.completedFuture(null);
}
}
@Autowired
private AsyncService asyncService;
@RequestMapping("/test")
public void test() {
for (int i = 0; i < 5; i++) {
asyncService.async();
}
System.out.println("Return from Controller");
}
public static void main(String[] args) {
SpringApplication.run(AsyncApp.class, args);
}
}
输出结果为:
Return from Controller
Hello from Rules-2
Hello from Rules-1
Hello from Rules-2
Hello from Rules-1
Hello from Rules-2
答案 1 :(得分:1)
最后,我得到了解决方案。首先,我必须指定bean的名称并在Async2类中使用bean名称。
@Bean(name="rulesThreadExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Rules-");
executor.initialize();
return executor;
}
@Async("rulesThreadExecutor")
public CompletableFuture<Void> anotherMethod(int i) {
LOGGER.info("hello world");
return CompletableFuture.completedFuture(null);
}