public class AnswerApp { public static void main(String[] args) throws Exception { ExecutorService executorService = Executors.newCachedThreadPool(); Future<Integer> future = executorService.submit(() -> { logger("模拟异步耗时任务开始..."); try { // 模拟耗时任务 Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } logger("模拟异步耗时任务结束!!!"); return 10; }); //当前线程继续作其余事情 logger("处理其余事情...\n"); // 当前主线程阻塞, 直到获取异步操做的结果 Integer result = future.get(); logger("result: " + result); } }
程序运行结果
java
2019-06-28 18:20:22:618 模拟异步耗时任务开始... 2019-06-28 18:20:22:618 处理其余事情... 2019-06-28 18:20:27:622 模拟异步耗时任务结束!!! 2019-06-28 18:20:27:622 result: 10
public class AnswerApp { public static void main(String[] args) throws Exception { FutureTask<Integer> futureTask = new FutureTask<>(() -> { logger("异步耗时任务开始..."); // 模拟耗时任务 Thread.sleep(5000); return 100; }); ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(futureTask); // 阻塞, 直到获取异步任务结果 logger("result: " + futureTask.get()); executorService.shutdown(); } }
程序运行结果
web
2019-06-28 18:14:46:272 异步耗时任务开始... 2019-06-28 18:14:51:274 result: 100
Future 接口能够执行异步任务,但却有其局限性。 它很难直接表述多个 Future 结果之间的依赖性。异步
public class AnswerApp { public static void main(String[] args) throws Exception { CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> { logger("获取数据(耗时任务)开始..."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } logger("已经拿到数据啦~~~"); return 10; }).thenApply((data) -> { logger(MessageFormat.format("对拿到的·数据{0}·进行加工处理...", data)); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return data * data; }).whenCompleteAsync((r, e) -> logger("最终数据: " + r)); logger("主线程正在执行耗时任务\n"); Thread.sleep(3000); logger("主线程耗时任务执行完成\n"); completableFuture.get(); } }
程序运行结果
svg
2019-06-28 19:18:40:947 获取数据(耗时任务)开始... 2019-06-28 19:18:40:947 主线程正在执行耗时任务 2019-06-28 19:18:43:952 主线程耗时任务执行完成 2019-06-28 19:18:45:951 已经拿到数据啦~~~ 2019-06-28 19:18:45:971 对拿到的·数据10·进行加工处理... 2019-06-28 19:18:47:972 最终数据: 100
public class AnswerApp { public static void main(String[] args) throws Exception { CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> { logger("数据提取数据(耗时任务)..."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } logger("数据已经拿到啦~~~"); return 10; }).thenCompose(preRlt -> CompletableFuture.supplyAsync(() -> { logger("我拿到了上一步任务的数据啦~ preRlt: " + preRlt); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } return 10 + preRlt; })); logger("最终结果数据: " + completableFuture.get()); } }
程序运行结果
spa
2019-06-28 18:31:44:491 数据提取数据(耗时任务)... 2019-06-28 18:31:49:496 数据已经拿到啦~~~ 2019-06-28 18:31:49:499 我拿到了上一步任务的数据啦~ preRlt: 10 2019-06-28 18:31:54:501 最终结果数据: 20
public class AnswerApp { public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); CompletableFuture<Integer> completableFuture1 = CompletableFuture.supplyAsync(() -> { logger("耗时·任务1·准备开始..."); try { // 模拟耗时任务1 Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } logger("我已经拿到耗时·任务1·的数据啦~~~"); return 10; }); CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> { logger("耗时·任务2·准备开始..."); try { // 模拟耗时任务2 Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } logger("我已经拿到耗时·任务2·的数据啦~~~"); return 20; }); CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(completableFuture1, completableFuture2); // 这个方法不会合并结果,能够看到他的返回值是 Void 类型 combinedFuture.get(); Optional<Integer> sum = Stream.of(completableFuture1, completableFuture2).map(CompletableFuture::join).reduce((x, y) -> x + y); logger("两个任务的结果和: " + String.valueOf(sum.orElse(0))); logger("程序总共耗时 " + (System.currentTimeMillis() - start) / 1000 + " s"); }
程序运行结果
线程
2019-06-28 19:04:20:936 耗时·任务2·准备开始... 2019-06-28 19:04:20:936 耗时·任务1·准备开始... 2019-06-28 19:04:23:939 我已经拿到耗时·任务2·的数据啦~~~ 2019-06-28 19:04:25:939 我已经拿到耗时·任务1·的数据啦~~~ 2019-06-28 19:04:25:943 两个任务的结果和: 30 2019-06-28 19:04:25:943 程序总共耗时 5 s
public class AnswerApp { public static void main(String[] args) throws Exception { String name = null; // 第一个参数为 CompletableFuture 返回的结果, 第二个参数为抛出的异常 // s: CompletableFuture 返回的结果, t: 抛出的异常 CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> { Assert.notNull(name, "name is null"); return MessageFormat.format("hello {0}", name); }).handle((s, t) -> s != null ? s : t.getMessage()); logger("最终拿到的结果1: " + completableFuture1.get()); System.out.println(); String userName = "answer"; CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> { Assert.notNull(userName, "userName is null"); return MessageFormat.format("hello {0}", userName); }).handle((s, t) -> s != null ? s : t.getMessage()); logger("最终拿到的结果2: " + completableFuture2.get()); } }
程序运行结果
日志
2019-06-28 19:07:38:136 最终拿到的结果1: java.lang.IllegalArgumentException: name is null 2019-06-28 19:07:38:139 最终拿到的结果2: hello answer
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS"); private static void logger(String log) { System.out.println(MessageFormat.format("{0} {1}", LocalDateTime.now().format(FORMATTER), log)); }