zoukankan      html  css  js  c++  java
  • spring学习(二十七)--@Async

    在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在spring 3.x之后,就已经内置了@Async来完美解决这个问题。

    1.  何为异步调用?

        在解释异步调用之前,我们先来看同步调用的定义;同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。 异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕;而是继续执行下面的流程。

         例如, 在某个调用中,需要顺序调用 A, B, C三个过程方法;如他们都是同步调用,则需要将他们都顺序执行完毕之后,方算作过程执行完毕; 如B为一个异步的调用方法,则在执行完A之后,调用B,并不等待B完成,而是执行开始调用C,待C执行完毕之后,就意味着这个过程执行完毕了。

    2.  常规的异步调用处理方式

        在Java中,一般在处理类似的场景之时,都是基于创建独立的线程去完成相应的异步调用逻辑,通过主线程和不同的线程之间的执行流程,从而在启动独立的线程之后,主线程继续执行而不会产生停滞等待的情况。或是使用TaskExecutor执行异步线程。

    3. @Async介绍

       在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。

       如何在Spring中启用@Async。基于Java配置的启用方式:在类上使用@Component、@EnableAsync,在类中的方法上使用@Async注解,那么该方法在被调用的时候就会在开辟的新线程中异步执行。

    package springAnnotions;
    
    import java.util.concurrent.Future;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.scheduling.annotation.AsyncResult;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.stereotype.Component;
    
    /**
     * 开发多线程代码,有三种方法
     * 1、实现Runnable接口的run方法
     * 2、继承Thread接口重写run方法
     * 3、使用Callable和Future接口创建线程,这种可以获取返回值
     * 在spring中,使用@Aysnc可以被当作新的多线程方法,被@Aysnc注解的方法再被调用的时候,都会在新的线程中执行。
     * @author qiaozhong
     */
    @Component
    @EnableAsync
    public class AsyncAnnotion {
    
        /**
         * 无返回值的异步方法
         * @param i
         */
        @Async
        public void asyncTest(String i){
            try {
                System.out.println(i + "start!");
                Thread.sleep(1000);
                System.out.println(i + "end!");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        /**
         * 有返回值的异步方法
         * @param i
         * @return
         */
        @Async
        public Future<String> asyncReturnTest(String i){
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return new AsyncResult<String>(i);
        }
        
        /**
         * 无返回值的同步方法
         * @param i
         */
        public void notAsyncTest(String i){
            try {
                System.out.println(i + "start!");
                Thread.sleep(1000);
                System.out.println(i + "end!");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) throws InterruptedException {
            ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("springConfig/spring-all.xml");
            AsyncAnnotion asyncAnnotion = (AsyncAnnotion)ac.getBean(AsyncAnnotion.class);
            for (int i = 0; i < 3; i++) {
                asyncAnnotion.asyncTest(String.valueOf(i));
            }
            
            Thread.sleep(2000);
            
            for (int i = 0; i < 3; i++) {
                asyncAnnotion.notAsyncTest(String.valueOf(i));
            }
            
            Future<String> future;
            future = asyncAnnotion.asyncReturnTest(String.valueOf(5));
            do {
                if (future.isDone()) {
                    try {
                        System.out.println(future.get());
                        break;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } while (true);
        }
        
    }

    执行main函数结果:

    2start!
    0start!
    1start!
    0end!
    1end!
    2end!
    0start!
    0end!
    1start!
    1end!
    2start!
    2end!
    5

    个人理解,如有错误,欢迎指正!
  • 相关阅读:
    Blob
    MySQL This function has none of DETERMINISTIC, NO SQL...错误1418 的原因分析及解决方法 (转)
    事务--存储过程
    JDBC-Mysql-编译预处理(占位符)
    socket
    GUI---深度复制
    串行化--深度复制
    RESTful理解
    django中文和时区的配置
    redis-server报错
  • 原文地址:https://www.cnblogs.com/gllegolas/p/11817044.html
Copyright © 2011-2022 走看看