美文网首页
使用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