异步(async)是相对于同步(sync)来讲的,简单理解,同步是串行的,异步是并行的。git
比如说,A须要从B和C两个节点获取数据github
第一种方式,A请求B,B返回给A数据,A再去请求C,在从C出得到数据。这种方式就是同步。算法
另外一种方式,A去请求B,不等B返回数据,就去请求C,而后等B和C准备好数据再推送给A,A一样能够拿到B和C的数据,这就是异步。spring
注意,第二种方式B和C是同时处理A的请求的,是比第一种方式效率要高的,可是这种方式,有一个限制,就是从B和C之间要获取的数据不能有依赖关系,假如获取C的数据时候,C须要从B返回来的数据,那就只能采用第一种方式,先请求B,拿到B的数据,在去请求C。缓存
举个比较直白的例子,把订外卖抽象成几步springboot
按照同步方式处理,1,2,3,4加起来20分钟时间。
异步
可是餐厅作饭和找外卖小哥严格意义上没有依赖关系,2和3是能够同时进行的,这样算,就只须要15分钟。
async
异步和同步是两种处理方式,同步适用的场景多,编码简单,便于理解,可是在某些特定的场景下异步比同步效率会高出不少。spring-boot
1) Application添加注解 @EnableAsync
测试
@EnableAsync @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
@EnableAsync 表示支持异步任务,springboot对于异步,定时,缓存,切面等的配置都是经过在启动类上加 @EnableXXX来配置的。
2) 异步任务类添加 @Component
注解
表示把任务类当成一个组件注册,这样调用时候能够直接注入。
3) 异步方法添加 @Async
注解
表示该方法会异步执行,也就是说主线程会直接跳过该方法,而是使用线程池中的线程来执行该方法。
@Component public class AsyncTask { @Async public Future<String> execTaskA() throws InterruptedException { System.out.println("TaskA开始"); long star = new Date().getTime(); Thread.sleep(5000); long end = new Date().getTime(); System.out.println("TaskA结束,耗时毫秒数:" + (end - star)); return new AsyncResult<>("TaskA结束"); } @Async public Future<String> execTaskB() throws InterruptedException { System.out.println("TaskB开始"); long star = new Date().getTime(); Thread.sleep(3000); long end = new Date().getTime(); System.out.println("TaskB结束,耗时毫秒数:" + (end - star)); return new AsyncResult<>("TaskB结束"); } @Async public Future<String> execTaskC() throws InterruptedException { System.out.println("TaskC开始"); long star = new Date().getTime(); Thread.sleep(4000); long end = new Date().getTime(); System.out.println("TaskC结束,耗时毫秒数:" + (end - star)); return new AsyncResult<>("TaskC结束"); } }
4)测试类测试
@RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class ApplicationTests { @Autowired AsyncTask asyncTask; @Test public void testAsyncTask() throws InterruptedException { long star = new Date().getTime(); System.out.println("任务开始,当前时间" +star ); Future<String> taskA = asyncTask.execTaskA(); Future<String> taskB = asyncTask.execTaskB(); Future<String> taskC = asyncTask.execTaskC(); //间隔一秒轮询 直到 A B C 所有完成 while (true) { if (taskA.isDone() && taskB.isDone() && taskC.isDone()) { break; } Thread.sleep(1000); } long end = new Date().getTime(); System.out.println("任务结束,当前时间" + end); System.out.println("总耗时:"+(end-star)); } }
执行结果
或者 git clone -b async git@github.com:DannyJoe1994/spring-boot.git