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事务注解在同一个方法上同时使用,不然事务注解将无效。

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

  • 相关阅读:
    【Mysql学习笔记】浅析mysql的binlog
    HBase 学习笔记---守护进程及内存调优
    字符集例子-同一字符不同字符集编码不同及导入导出的乱码
    随机访问
    格式化的代价
    读写文本文件
    缓冲
    加速I/O的基本规则
    序列化再探讨
    数据库I/O:CMP、Hibernate
  • 原文地址:https://www.cnblogs.com/rinack/p/9934925.html
Copyright © 2011-2022 走看看