@Async方法中的Spring @Async方法

StO*_*StO 3 spring multithreading asynchronous threadpool

您好,我正在尝试 Springs 异步执行器,发现您可以使用 @Async。我想知道是否有可能使用@Asyncinside @Async,要求是将任务委托给@Async第一个@Async方法中调用的方法。

例如:一个目录中有 100 个文件,需要创建在 5 个线程中处理 20 个文件的作业。

Ran*_*ith 8

如果两个异步方法定义在两个不同的类中,那么您将能够从第一个异步方法调用第二个异步方法。但是,如果它们都在同一个类中,则第二个方法的执行将在处理第一个方法本身的线程中内联发生。查看答案以获取更多详细信息以及一些解决方法。

对于您的具体情况,您可以定义两个线程池执行器,一个用于第一个异步方法,另一个用于第二个异步方法。该@Async注释有一个value参数,您可以将应使用的线程池执行器传递给该参数。

下面是使用两个执行器的示例。

@SpringBootApplication
@EnableAspectJAutoProxy
@EnableAsync
public class MultipleExecutorsExample {

    @Bean
    public ThreadPoolTaskExecutor executor1() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(10);
        threadPoolTaskExecutor.setMaxPoolSize(10);
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

    @Bean
    public ThreadPoolTaskExecutor executor2() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(5);
        threadPoolTaskExecutor.setMaxPoolSize(5);
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

    public static void main(String[] args) throws BeansException, InterruptedException {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(MultipleExecutorsExample.class)
                .web(WebApplicationType.NONE).build().run(args);
        context.getBean(Service1.class).execute();
    }

}
Run Code Online (Sandbox Code Playgroud)

Service1 具有第一个异步方法

@Component
@Slf4j
public class Service1 {

    @Autowired
    private Service2 service2;

    @Async("executor1")
    public void execute() throws InterruptedException {
        log.info("Sleeping for 5 seconds");
        for (int i = 1; i <= 10; i++) {
            service2.execute();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

Service2 与第二个异步方法

@Component
@Slf4j
public class Service2 {

    @Async("executor2")
    public void execute() throws InterruptedException {
        log.info("Sleeping for 1 seconds");
        Thread.sleep(1000);
    }

}
Run Code Online (Sandbox Code Playgroud)

程序的输出显示两个异步任务使用了不同的执行器。

018-05-30 18:44:27.557  INFO 19839 --- [  restartedMain] c.e.demo.tp.MultipleExecutorsExample     : Started MultipleExecutorsExample in 1.926 seconds (JVM running for 2.407)
2018-05-30 18:44:27.567  INFO 19839 --- [    executor1-1] com.example.demo.tp.Service1             : Sleeping for 5 seconds
2018-05-30 18:44:27.570  INFO 19839 --- [    executor2-1] com.example.demo.tp.Service2             : Sleeping for 1 seconds
2018-05-30 18:44:27.570  INFO 19839 --- [    executor2-2] com.example.demo.tp.Service2             : Sleeping for 1 seconds
2018-05-30 18:44:27.570  INFO 19839 --- [    executor2-5] com.example.demo.tp.Service2             : Sleeping for 1 seconds
Run Code Online (Sandbox Code Playgroud)

  • @StO是的,您可以为两个异步任务使用相同的线程池。不知何故,我假设您需要两个不同的线程池来执行两个异步任务。在某些情况下,我们使用多个线程池(例如:如果您有多个异步任务,例如处理文件、发送电子邮件等,并且您希望单个任务用完池中的所有线程,您可以配置不同的池每个任务)。对于您的用例,我认为单个线程池应该足够了。 (2认同)