美文网首页
使用Spring @Async 编写异步调用方法

使用Spring @Async 编写异步调用方法

作者: 狼團 | 来源:发表于2018-12-29 21:44 被阅读0次

    使用场景:发送邮件、日志记录、发短信等属于单一任务、耗时的非事务型操作,在简单的使用场景下使用异步方法调用可以快速实现。如场景较为复杂建议使用消息中间件服务(MQ),注意异步方法在执行期间如果服务被终止则可能造成任务被取消,需要自行实现数据恢复。

    以下演示2个异步调用方法,分别使用不同的 Executor:
    (1)一个是无需等待返回的异步方法;
    (2)一个是利用Future的异步调用方法,可接收返回值。

    一、定义异步Executor(线程池)

    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    import java.util.concurrent.Executor;
    
    @EnableAsync // 启动异步调用
    @Configuration
    public class AsyncConfigSupport extends AsyncConfigurerSupport {
        @Bean(name = "executorOne")
        public Executor getAsyncExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(10);
            executor.setMaxPoolSize(100);
            executor.setQueueCapacity(100);
            executor.setThreadNamePrefix("CSISTP-");
            executor.initialize();
            return executor;
        }
    
        @Bean
        public Executor executorTwo() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(10);
            executor.setMaxPoolSize(100);
            executor.setQueueCapacity(100);
            executor.setThreadNamePrefix("CSISTP-");
            executor.initialize();
            return executor;
        }
    }
    

    二、在需要进行异步调用的方法增加异步调用注解,2个方法分别使用不同的 Executor

    @Service
    public class ExampleService{
        @Async("executorOne") // 可以不指定,默认使用 getAsyncExecutor (即本示例的 executorOne) 
        public void notifyMessageWithoutReturn(){
            try {
                log.info("notifyMessageWithoutReturn...");
                log.info("notifyMessage>wait...");
                Thread.sleep(1000*3);
                log.info("notifyMessage>OK!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        @Async("executorTwo")
        public Future<String> notifyMessageWithReturn(){
            Future<String> future;
            try {
                log.info("notifyMessageWithReturn...");
                Thread.sleep(1000 * 3);
                future = new AsyncResult<String>("success!" );
            } catch (InterruptedException e) {
                future = new AsyncResult<String>("error");
            }
            return future;
        }
    }
    

    三、方法调用测试

    @Autowired
    ExampleService  exampleService
    @Test
    public void testAsync() throws Exception {
        // 同步方法调用
            this.exampleService.notifyMessageWithoutReturn();
            Future<String> future = this.exampleService.notifyMessageWithReturn();
            while(true){
                // 等待返回
                if (future.isDone()){
                    System.out.println("done, result="+future.get());
                    break;
                }
                System.out.println("not finish yet");
                Thread.sleep(100);
            }
        }
    

    相关文章

      网友评论

          本文标题:使用Spring @Async 编写异步调用方法

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