代码之家  ›  专栏  ›  技术社区  ›  hades

Springboot异步方法在同一线程中运行

  •  0
  • hades  · 技术社区  · 7 年前

    我正在测试 @Async

    我的配置类:

    @Configuration
    @EnableAsync
    public class AsyncConfig {
    
        @Bean
        public Executor asyncExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(5);
            executor.setMaxPoolSize(5);
            executor.setQueueCapacity(500);
            executor.setThreadNamePrefix("Async Process-");
            executor.initialize();
            return executor;
        }
    }
    

    @GetMapping("/test/async")
    public void testAsync() {
        System.err.println("Thread in controller: " + Thread.currentThread().getName());
        TestAsyncClazz clazz = new TestAsyncClazz();
        clazz.testAsyncMethod();
    }
    

    我的 TestAsyncClass :

    public class TestAsyncClazz {
    
        @Async
        public void testAsyncMethod(){
            System.err.println("Running async: "+ Thread.currentThread().getName());
        }
    }
    

    Async Process- :

    Thread in controller: http-nio-8080-exec-2
    Running async: http-nio-8080-exec-2
    

    我做错了什么?我误解了什么吗?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Jesper    7 年前

    之所以会发生这种情况,是因为您正在使用自己实例化的类上调用异步方法 new

    TestAsyncClazz clazz = new TestAsyncClazz();
    clazz.testAsyncMethod();
    

    这只会以您期望的方式在Springbean上工作——换句话说,不要实例化 TestAsyncClazz 你自己定义该类的Springbean实例,将该bean自动连接到控制器中,然后调用该bean上的方法。

    例子:

    @Configuration
    @EnableAsync
    public class AsyncConfig {
    
        @Bean
        public Executor asyncExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(5);
            executor.setMaxPoolSize(5);
            executor.setQueueCapacity(500);
            executor.setThreadNamePrefix("Async Process-");
            executor.initialize();
            return executor;
        }
    
        // Define a Spring bean of type TestAsyncClazz
        @Bean
        public TestAsyncClazz testAsyncClazz() {
            return new TestAsyncClazz();
        }
    }
    
    @Controller
    public class MyController {
    
        // Inject the bean here
        @Autowired 
        private TestAsyncClazz testAsyncClass;
    
        @GetMapping("/test/async")
        public void testAsync() {
            System.err.println("Thread in controller: " +
                    Thread.currentThread().getName());
    
            // Use the bean instead of instantiating the class yourself
            testAsyncClass.testAsyncMethod();
        }
    }