1 直接上代碼吧。java版本的。
背景是我有一個需求是用戶注銷。注銷時我需要判斷是否有訂單,結算單等業務。這樣我就需要調用其他業務線的接口。
接口需要調用N個(這里是5個)分別判斷是否允許注銷。
悲觀假設每個接口調用要1s那么5個接口就需要5s以上,並且任何一個不可行則整個判斷將不通過。
這時候就需要用到異步任務並行。 這里采用
CompletableFuture的thenCombine 來實現多個異步任務並行。代碼簡單。將兩個test跑一下就可以看到效果,
異常case是將userId寫成 >100的值。第4個任務將會拋錯。這樣就可以看到整體運行結果。
當然拋錯也可以轉換為自己認識的錯誤方式,由調用方來決定是否繼續往下走。
本文為原創,雖然例子很簡單但是可以解決我的需求。分享出來希望能幫到您,
當然如果您有更好的方式歡迎留言共同探討,我的郵箱 375341227@qq.com 有更好的歡迎共同探討。
2 3 import java.util.concurrent.CompletableFuture; 4 import lombok.extern.slf4j.Slf4j; 5 import org.junit.Test; 6 7 @Slf4j 8 public class SupplyAsyncText { 9 10 @Test 11 public void testSyncLogOff() { 12 int userId = 45; 13 // 同步 14 long begin = System.currentTimeMillis(); 15 StringBuilder sb = new StringBuilder(); 16 sb.append(canDo1(userId)); 17 sb.append(canDo2(userId)); 18 sb.append(canDo3(userId)); 19 sb.append(canDo4(userId)); 20 sb.append(canDo5(userId)); 21 long end = System.currentTimeMillis(); 22 // 每一個執行1s 同步:結果是執行應該是 > 5s 的 23 log.info("noUseAsync |{}|{} s", sb.toString(), (end - begin) / 1000.0); 24 } 25 26 @Test 27 public void testCanLogOff() { 28 // case 設定:如果 userId > 100 則在某一個環節拋錯 29 int userId = 10; 30 // 異步 每一個執行1s 異步並行:結果是執行應該 < 5s 31 long begin2 = System.currentTimeMillis(); 32 String result = 33 CompletableFuture.supplyAsync(() -> canDo1(userId)) 34 .thenCombine(CompletableFuture.supplyAsync(() -> canDo2(userId)), (s1, s2) -> s1 + s2) 35 .thenCombine(CompletableFuture.supplyAsync(() -> canDo3(userId)), (s1, s2) -> s1 + s2) 36 .thenCombine(CompletableFuture.supplyAsync(() -> canDo4(userId)), (s1, s2) -> s1 + s2) 37 .thenCombine(CompletableFuture.supplyAsync(() -> canDo5(userId)), (s1, s2) -> s1 + s2) 38 .exceptionally( 39 e -> { 40 log.error("exception: ", e); 41 return e.getMessage(); 42 }) 43 .join(); 44 long end2 = System.currentTimeMillis(); 45 log.info("supplyAsync|{}|{} s", result, (end2 - begin2) / 1000.0); 46 } 47 48 private String canDo1(int userId) { 49 try { 50 Thread.sleep(1000); 51 } catch (InterruptedException e) { 52 e.printStackTrace(); 53 } 54 return "ok"; 55 } 56 57 private String canDo2(int userId) { 58 try { 59 Thread.sleep(1000); 60 } catch (InterruptedException e) { 61 e.printStackTrace(); 62 } 63 return "ok"; 64 } 65 66 private String canDo3(int userId) { 67 try { 68 Thread.sleep(1000); 69 } catch (InterruptedException e) { 70 e.printStackTrace(); 71 } 72 return "ok"; 73 } 74 75 private String canDo4(int userId) { 76 try { 77 Thread.sleep(1000); 78 } catch (InterruptedException e) { 79 e.printStackTrace(); 80 } 81 if (userId > 100) { 82 throw new RuntimeException(String.format("用戶[%s]還有訂單,不可注銷",userId)); 83 } 84 return "ok"; 85 } 86 87 private String canDo5(int userId) { 88 try { 89 Thread.sleep(1000); 90 } catch (InterruptedException e) { 91 e.printStackTrace(); 92 } 93 return "ok"; 94 } 95 }