java 异步
注:本文基于 jdk1.8
1. 异步不需要返回值;
CompletableFuture.runAsync()
示例代码如下:
public JsonResult test() { JsonResult result = new JsonResult(); CompletableFuture.runAsync(() -> { // 准备请求 JsonResult postResult = appTool.postRequest(url, params, headers); // 请求结果处理 if (!postResult.getCode().equals("0")) { // 请求失败 logger.error("请求失败"); } }); return result; }
在上述代码中,把一个请求异步执行,方法不必等待post请求结束;
2.异步需要返回值;
CompletableFuture.supplyAsync()
示例代码如下:
public String test() { CompletableFuture<JsonResult> future = CompletableFuture.supplyAsync(() -> { // 准备请求 JsonResult postResult = appTool.postRequest(url, params, headers); return postResult.getCode(); }); // get() 方法会一直堵塞,直到 feature 完成。result 就是异步结果;此处get() 要用 try-catch 包裹 String result = feature.get(); return result; }
3. 等待任意数量异步全部完成
CompletableFuture.allOf()
3.1 等待任意数量异步全部完成,不考虑异步结果;
示例代码如下:
public String test() { List<String> urls = Arrays.asList(...); List<CompletableFuture> contentFutures = urls.stream().map(url -> CompletableFuture.runAsync(() -> { // 准备请求 JsonResult postResult = appTool.postRequest(url); return postResult.getCode(); })).collect(Collectors.toList()); CompletableFuture<Void> allFutures = CompletableFuture.allOf( contentFutures.toArray(new CompletableFuture[contentFutures.size()]) ); // 等待异步全部结束 allFutures.join(); return "1"; }
此处使用了 join() 来等待异步结束,join() 和 get() 方法类似,区别是
join() 会抛出 unchecked exception;get() 抛出 checked exception 必须用 try-catch 包裹
3.2. 等待任意数量异步全部完成,需要异步返回结果;
示例代码如下:
public String test() { List<String> urls = Arrays.asList(...); List<CompletableFuture> contentFutures = urls.stream().map(url -> CompletableFuture.supplyAsync(() -> { // 准备请求 JsonResult postResult = appTool.postRequest(url); return postResult.getCode(); })).collect(Collectors.toList()); CompletableFuture<List<String>> allFutures = CompletableFuture.allOf( contentFutures.toArray(new CompletableFuture[contentFutures.size()]) ).thenApply(v -> { return contentFutures.stream().map(contentFuture -> contentFuture.join()).collect(Collectors.toList()); }); try { // 等待异步并获取返回结果 设置等待时间40s List<String> data = allFutureResult.get(40, TimeUnit.SECONDS);
// "0" 失败 "1" 成功 return data.indexOf("0") > -1 ? "0" : "1"; } catch (Exception e) { logger.error(e); return "0"; } }
线程池
下一篇更新