文章插图
创建任务并执行任务无参创建
CompletableFuture<String> noArgsFuture = new CompletableFuture<>();
转入相应任务,无返回值runAsync方法可以在后台执行异步计算,但是此时并没有返回值 。持有一个Runnable对象 。CompletableFuture noReturn = CompletableFuture.runAsync(()->{ //执行逻辑,无返回值});
传入相应任务,有返回值此时我们看到返回的是CompletableFuture<T>此处的T就是你想要的返回值的类型 。其中的Supplier<T>是一个简单的函数式接口 。CompletableFuture<String> hasReturn = CompletableFuture.supplyAsync(new Supplier<String>() { @Override public String get() { return "hasReturn"; }});
此时可以使用lambda表达式使上面的逻辑更加清晰CompletableFuture<String> hasReturnLambda = CompletableFuture.supplyAsync(TestFuture::get);private static String get() { return "hasReturnLambda";}
获取返回值异步任务也是有返回值的,当我们想要用到异步任务的返回值时,我们可以调用CompletableFuture的get()阻塞,直到有异步任务执行完有返回值才往下执行 。我们将上面的get()方法改造一下,使其停顿十秒时间 。
private static String get() { System.out.println("Begin Invoke getFuntureHasReturnLambda"); try { Thread.sleep(10000); } catch (InterruptedException e) { } System.out.println("End Invoke getFuntureHasReturnLambda"); return "hasReturnLambda";}
然后进行调用public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<String> funtureHasReturnLambda = (CompletableFuture<String>) getFuntureHasReturnLambda(); System.out.println("Main Method Is Invoking"); funtureHasReturnLambda.get(); System.out.println("Main Method End");}
可以看到输出如下,只有调用get()方法的时候才会阻塞当前线程 。Main Method Is InvokingBegin Invoke getFuntureHasReturnLambdaEnd Invoke getFuntureHasReturnLambdaMain Method End
自定义返回值除了等待异步任务返回值以外,我们也可以在任意时候调用complete()方法来自定义返回值 。CompletableFuture<String> funtureHasReturnLambda = (CompletableFuture<String>) getFuntureHasReturnLambda();System.out.println("Main Method Is Invoking");new Thread(()->{ System.out.println("Thread Is Invoking "); try { Thread.sleep(1000); funtureHasReturnLambda.complete("custome value"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread End ");}).run();String value = funtureHasReturnLambda.get();System.out.println("Main Method End value is "+ value);
我们可以发现输出是新起线程的输出值,当然这是因为我们的异步方法设置了等待10秒,如果此时异步方法等待1秒,新起的线程等待10秒,那么输出的值就是异步方法中的值了 。Main Method Is InvokingBegin Invoke getFuntureHasReturnLambdaThread Is Invoking Thread End Main Method End value is custome value
按顺序执行异步任务如果有一个异步任务的完成需要依赖前一个异步任务的完成,那么该如何写呢?是调用get()方法获得返回值以后然后再执行吗?这样写有些麻烦,CompletableFuture为我们提供了方法来完成我们想要顺序执行一些异步任务的需求 。thenApply、thenAccept、thenRun这三个方法 。这三个方法的区别就是 。
推荐阅读
- 开源JavaScript实用日期处理库——date-fns
- 在浏览器中异步下载文件监听下载进度
- SpringMVC:进阶
- EditPlus——一款小巧功能强大的老牌代码文本编辑器
- 程序员必备技能:设计模式之——组合模式
- CSS样式更改——字体设置Font&边框Border
- 一文全解析——APP版本管理基本知识
- CSS样式更改——文本Content
- 一个漂亮的开源HTML5音乐播放器——APlayer
- 万兆电口网卡体验——安装篇