• spring@Async注解实现异步方法调用


    概述

    如何实现异步方法调用,很多人首先会想到使用线程或者线程池技术,springboot中有一个很简单的方法可以实现异步方法调用,那就是在方法上使用@Async注解

    例子

    首先在Springboot启动类上添加@EnableAsync注解,表明使用@Async注解

    @SpringBootApplication
    @EnableAsync
    public class Application{
    
    public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
    }
    }
    

    异步调用测试类

    package com.example.mongo_demo.test;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Component;
    
    /**
    * created by qinming on 2018/5/17
    **/
    @Component
    public class AsyncTest {
    public static final Logger LOGGER = LoggerFactory.getLogger(AsyncTest.class);
    
    @Async
    public void asyn1() throws InterruptedException {
    Long timeMilles = System.currentTimeMillis();
    Thread.sleep(7000);
    LOGGER.error("》》》》》》》》》》》》asyn1耗时:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles);
    }
    @Async
    public void asyn2() throws InterruptedException {
    Long timeMilles = System.currentTimeMillis();
    Thread.sleep(7000);
    LOGGER.error("》》》》》》》》》》》》asyn2耗时:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles);
    }
    @Async
    public void asyn3() throws InterruptedException {
    Long timeMilles = System.currentTimeMillis();
    Thread.sleep(10000);
    LOGGER.error("》》》》》》》》》》》》asyn3耗时:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles);
    }
    }
    

    通过一个简单的接口测试即可

    /**
    * created by qinming on 2018/5/17
    **/
    @RestController
    @RequestMapping("/api")
    public class DemostrationController {
    @Autowired
    private AsyncTest asyncTest;
    public static final Logger LOGGER = LoggerFactory.getLogger(DemostrationController.class);
    @RequestMapping("/async/test")
    public String get() throws InterruptedException {
    long timeMillis = System.currentTimeMillis();
    asyncTest.asyn1();
    asyncTest.asyn2();
    asyncTest.asyn3();
    Thread.sleep(1000);
    LOGGER.error("//////耗时:{}",System.currentTimeMillis()-timeMillis);
    return "";
    }
    }
    
    

    结果如下:

    2018-05-17 14:27:40.252 ERROR 7843 --- [nio-8080-exec-1] c.e.m.ctrl.DemostrationController : //////耗时:1019
    2018-05-17 14:27:46.253 ERROR 7843 --- [cTaskExecutor-1] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn1耗时:7003《《《《《《《《《
    2018-05-17 14:27:46.255 ERROR 7843 --- [cTaskExecutor-2] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn2耗时:7005《《《《《《《《《
    2018-05-17 14:27:49.254 ERROR 7843 --- [cTaskExecutor-3] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn3耗时:10004《《《《《《《《《
    
    

    这样就实现了异步方法的简单调用

    带有返回值的方法如何使用@Async注解

    使用@Async注解的方法返回值为java.util.concurrent.Future 的实现类 org.springframework.scheduling.annotation.AsyncResult 类型,代码如下:

    /**
    * created by qinming on 2018/5/17
    **/
    @Component
    public class AsyncWIthReturnValueTest {
    public static final Logger LOGGER = LoggerFactory.getLogger(AsyncWIthReturnValueTest.class);
    
    @Async
    public Future<String> aysnc1() throws InterruptedException {
    Long st = System.currentTimeMillis();
    LOGGER.error(">>>>>>>aysnc1 start at {}>>>>>",st);
    Thread.sleep(7000);
    long end =System.currentTimeMillis();
    LOGGER.error(">>>>>>>aysnc1 cost :{}>>>>>",end - st);
    return new AsyncResult<String>("aysnc1 is done");
    }
    @Async
    public Future<String> aysnc2() throws InterruptedException {
    Long st = System.currentTimeMillis();
    LOGGER.error(">>>>>>>aysnc2 start at {}>>>>>",st);
    Thread.sleep(7000);
    long end =System.currentTimeMillis();
    LOGGER.error(">>>>>>>aysnc2 cost :{}>>>>>",end - st);
    return new AsyncResult<String>("aysnc2 is done");
    }
    @Async
    public Future<String> aysnc3() throws InterruptedException {
    Long st = System.currentTimeMillis();
    LOGGER.error(">>>>>>>aysnc3 start at {}>>>>>",st);
    Thread.sleep(7000);
    long end =System.currentTimeMillis();
    LOGGER.error(">>>>>>>aysnc3 cost :{}>>>>>",end - st);
    return new AsyncResult<String>("aysnc3 is done");
    }
    }
    

    调用方法例子如下:

    @RequestMapping("/async/test")
    public String get() throws InterruptedException, ExecutionException {
    long timeMillis = System.currentTimeMillis();
    Future<String> async1 = asyncWIthReturnValueTest.aysnc1();
    Future<String> async2 = asyncWIthReturnValueTest.aysnc2();
    Future<String> async3 = asyncWIthReturnValueTest.aysnc3();
    while (true) {
    if (async1.isDone()){
    LOGGER.error("----{}1-------",async1.get());
    }
    if (async2.isDone()){
    LOGGER.error("----{}2-------",async2.get());
    }
    if (async3.isDone()){
    LOGGER.error("----{}3-------",async3.get());
    }
    if (async1.isDone() && async2.isDone() && async3.isDone()) {
    break;
    }
    Thread.sleep(1000);
    }
    LOGGER.error("//////耗时:{}",System.currentTimeMillis()-timeMillis);
    return "SUCCESS";
    }
    
  • 相关阅读:
    读书笔记Review: HTTP and HttpServletRequest
    读书笔记JavaScript Patterns_chapter6_Code Reuse Patterns
    读书笔记Review: servlet lifecycle and API
    读书笔记Review: HttpServletResponse
    简单分析Ext.ComponentMgr 函数
    翻译 Extjs in action中的Event flow in the DOM
    struts中的web.xml
    读书笔记_Extjs In Action_The Component Life Cycle
    web service中的事件
    Remoting学习笔记
  • 原文地址:https://www.cnblogs.com/myblogs-miller/p/9052011.html
Copyright © 2020-2023  润新知