在执行程序中指定线程池大小不起作用

Specifying thread pool size in executor doesn't work

我有一个 spring 启动项目。我正在尝试异步调用一些方法。我遵循了这个文档: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。但是当我调用 async 方法 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);
    }
}

更新2

@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();
    }
}

似乎未加载您使用自定义 asyncExecutor 配置 class。检查它是否被 Spring 扫描并且存在 @EnableAsync 注释。同样在你的样本中 anotherMethod 没有 return 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

终于找到解决办法了。首先,我必须指定 bean 的名称并在 Async2 class.

中使用 bean-name
@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);
}