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

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

  • 相关阅读:
    Web负载均衡的几种实现方式
    DNS负载均衡
    NoSQL开篇——为什么要使用NoSQL
    mySQL优化 my.ini 配置说明
    mysql性能优化-慢查询分析、优化索引和配置
    MySQL性能优化的最佳20+条经验
    IOS的UIPickerView 和UIDatePicker
    IOS的KVC
    IOS中的通知NSNotification
    IOS对话框UIAlertView
  • 原文地址:https://www.cnblogs.com/rinack/p/9934925.html
Copyright © 2011-2022 走看看