在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
原文:https://www.cnblogs.com/gllegolas/p/11817044.html