美文网首页
Spring Boot 微服务异步调用 @EnableAsync

Spring Boot 微服务异步调用 @EnableAsync

作者: yichen_china | 来源:发表于2022-02-16 14:03 被阅读0次

    第一步:在Application启动类上面加上@EnableAsync注解

    
    @SpringBootApplication
    @EnableAsync
    public class Application {
     
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    

    第二步:定义[线程池]

    @Configuration
    @EnableAsync
    @Component
    public class AsyncConfig {
     
        @Bean("asyncTaskExecutor")
        public TaskExecutor asyncTaskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            // 设置核心线程数
            executor.setCorePoolSize(20);
            // 设置最大线程数
            executor.setMaxPoolSize(100);
            // 设置队列容量
            executor.setQueueCapacity(1000);
            // 设置线程活跃时间(秒)
            executor.setKeepAliveSeconds(300);
            // 设置默认线程名称
            executor.setThreadNamePrefix("async-thread-pool-");
            // 设置拒绝策略
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
            // 等待所有任务结束后再关闭线程池
            executor.setWaitForTasksToCompleteOnShutdown(true);
            return executor;
        }
     
    }
    

    第三步:在异步方法上添加@Async

    @Slf4j
    @Service
    @Component
    public class AsyncServiceImpl implements AsyncService {
     
        
        @Async("asyncTaskExecutor")
        @Override
        public void testA() {
            try {
                System.out.println("开始testA");
                Thread.sleep(3000);
                System.out.println("完成testA");
                Thread currentThread = Thread.currentThread();
                System.out.println("任务testA,当前线程:" + currentThread.getName());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
     
        @Override
        public void testB() {
            try {
                System.out.println("开始testB");
                Thread.sleep(3000);
                System.out.println("完成testB");
                Thread currentThread = Thread.currentThread();
                System.out.println("任务testB,当前线程:" + currentThread.getName());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
     
    }
    

    第四步:测试

    public class Test {
        @Autowired
        private AsyncService asyncService;
     
        @Test
        public void testSyncTasks() throws Exception {
            long start = currentTimeMillis();
            asyncService.testA();
            long end = currentTimeMillis();
            System.out.println("时间testA:" + (end - start));
     
            long start1 = currentTimeMillis();
            asyncService.testB();
            long end1 = currentTimeMillis();
            System.out.println("时间testB:" + (end1 - start1));
        }
    }
    

    输出结果:

    时间testA:2
    开始testB
    开始testA
    完成testA
    完成testB
    任务testA,当前线程:async-thread-pool-1
    时间testB:3002
    异步方法@Async注解失效情况:

    (1)在@SpringBootApplication启动类没有添加注解@EnableAsync

    (2)调用方法和异步方法写在同一个类,需要在不同的类才能有效。

    (2)调用的是静态(static )方法

    (3)调用(private)私有化方法

    个别失效报错情况:

    报错一:提示需要在@EnableAsync上设置proxyTargetClass=true来强制使用基于cglib的代理。注解上加上即可。

    @EnableAsync(proxyTargetClass = true)
    Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching

     
    ————————————————

    相关文章

      网友评论

          本文标题:Spring Boot 微服务异步调用 @EnableAsync

          本文链接:https://www.haomeiwen.com/subject/mwfdlrtx.html