異步(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