zoukankan      html  css  js  c++  java
  • Spring开启方法异步执行

    @EnableAsync

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AsyncConfigurationSelector.class)
    public @interface EnableAsync {
    
        Class<? extends Annotation> annotation() default Annotation.class;
    
        boolean proxyTargetClass() default false;
    
        AdviceMode mode() default AdviceMode.PROXY;
    
        int order() default Ordered.LOWEST_PRECEDENCE;
    
    }

    @EnableAsync注解即开启Spring对方法异步执行的能力,需要和注解@Configuration配合使用。

    @Configuration
    @EnableAsync
    public class AppConfig {
    
    }

    也可以自定义线程池

    @Configuration
     @EnableAsync
     public class AppConfig implements AsyncConfigurer {
    
         @Override
         public Executor getAsyncExecutor() {
             ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
             executor.setCorePoolSize(7);
             executor.setMaxPoolSize(42);
             executor.setQueueCapacity(11);
             executor.setThreadNamePrefix("MyExecutor-");
             executor.initialize();
             return executor;
         }
    
         @Override
         public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
             return MyAsyncUncaughtExceptionHandler();
         }
     }

    @Async

    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Async {
    
        String value() default "";
    
    }

    在要异步执行的方法上使用@Async注解,下面是一个没有返回值,一个带有返回值的异步调用的示例。

    @Component
    public class AsyncTask {
    
        @Async
        public void task1() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        @Async
        public Future<String> task2() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new AsyncResult<String>("javastack");  
        }
    
    }

    测试代码

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class AsyncTest {
    
        private final static Logger log = LoggerFactory.getLogger(AsyncTest.class);
    
        @Autowired
        private AsyncTask asyncTask;
    
        @Test
        public void testTask1(){
            log.info("start");
            asyncTask.task1();
            log.info("finish");
        }
    
        @Test
        public void testTask2()  {
            log.info("start");
            Future<String> future = asyncTask.task2();
            while (true) {
                if (future.isDone()) {
                    try {
                        log.info("result is " + future.get());
                    } catch (Exception e) {
                        e.printStackTrace();
                    } 
                    break;
                }
            }
            log.info("finish");
        }
    
    }

    注意事项

    1、使用注意

    @Async只能使用到被代理的对象方法上,即代理类的入口方法处,且方法必须是public的。

    2、事务处理机制

    使用@Async异步注解不能和@Transaction事务注解在同一个方法上同时使用,不然事务注解将无效。

    要使用事务,需要把事务注解提取到方法里面的子方法上。

    欢迎大家转发到朋友圈,和朋友们一起提升自己。

    推荐阅读

    干货:2TB架构师四阶段视频教程

    面经:史上最全Java多线程面试题及答案

    面经:史上最全阿里高级Java面试题

    面经:史上最全Spring面试题

    教程:最全Spring Boot全套视频教程

    书籍:进阶Java架构师必看的15本书

    工具:推荐一款在线创作流程图、思维导图软件

    分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。

  • 相关阅读:
    Spring DI模式 小样例
    java中经常使用的日期格式化(全)
    循环-15. 统计素数并求和(20)
    [Unity3D]Unity3D游戏开发之自己主动寻路与Mecanim动画系统的结合
    【UVA】11732
    Mac OS使用技巧之十六:系统失去响应怎么办?
    C# 保存窗口为图片(保存纵断面图)
    Linux Resin 安装
    Etcd学习(二)集群搭建Clustering
    android中选择控件与选择界面自然过度效果的实现--一种新的交互设计
  • 原文地址:https://www.cnblogs.com/java-stack/p/11952618.html
Copyright © 2011-2022 走看看