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 }