CompletableFuture(它实现了 Future 接口) 和 Future 一样,可以作为函数调用的契约。当你向它请求获得结果,如果数据还没有准备好,请求线程就会等待,直到数据准备好后返回。
异步执行
@Test public void testFuture() throws ExecutionException, InterruptedException { long t1 = System.currentTimeMillis(); Future<List<Integer>> listFuture = getListAsync(); System.out.println("do something..."); Thread.sleep(2_000L); System.out.println("getList..."); System.out.println(listFuture.get()); System.out.println("spendTime = " + (System.currentTimeMillis() - t1)); } private Future<List<Integer>> getListAsync() { CompletableFuture<List<Integer>> resultFuture = new CompletableFuture<>(); new Thread( () -> { try { Thread.sleep(3_000L); resultFuture.complete(Lists.newArrayList(1, 2, 3)); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); return resultFuture; }
执行结果:
do something... getList... [1, 2, 3] spendTime = 3137
以上代码中,do something 指主线程在调用过 Future 的异步接口取得凭证后,即可继续向下执行,直至 getList 需要通过凭证取得异步计算结果时,再通过 get 的方式取得。
如果采用同步调用的方式,那么以上程序则需要 3 + 2 共 5s 的时间。
使用 supplyAsync 创建 CompletableFuture
CompletableFuture 提供了更轻巧的工厂方法
@Test public void testFuture() throws ExecutionException, InterruptedException { long t1 = System.currentTimeMillis(); // Future<List<Integer>> listFuture = getListAsync(); CompletableFuture<List<Integer>> listFuture = CompletableFuture.supplyAsync(OrderThriftServiceTest::getList); System.out.println("do something..."); Thread.sleep(2_000L); System.out.println("getList..."); System.out.println(listFuture.get()); System.out.println("spendTime = " + (System.currentTimeMillis() - t1)); } private static List<Integer> getList() { try { Thread.sleep(3_000L); return Lists.newArrayList(1,2,3,4,5); } catch (InterruptedException e) { e.printStackTrace(); return Lists.newArrayList(); } }