Future的用法

多线程场景时,一般是实现runnable接口,覆写run方法,返回值是void类型,因此这种情况下不需要线程的返回结果。 
如果需要线程的返回结果,就需要用callable接口来代替了。 
callable用法和runnable一样,只不过覆写的是call方法,该方法有一个泛型返回值类型,可以根据需要指定。 
那么何时到Future呢?当你启动callable线程时,就可以声明一个Future对象,用于接收返回结果。
Futrue可以监视目标线程调用call的情况,当你调用Future的get()方法以获得结果时,调用方的线程就被阻塞,直到目标线程的call方法结束并返回结果。
Future接口,一般都是取回Callable执行的状态用的。其中的主要方法:

  • cancel,取消Callable的执行,当Callable还没有完成时
  • get,获得Callable的返回值
  • isCanceled,判断是否取消了
  • isDone,判断是否完成

举个栗子。
四个刚需(线程)去买房摇号,future获取摇号结果。摇号结果未出,就一直阻塞。

public class FutureTest {/*** 买房摇号*/public static class Yaohao implements Callable<Integer> {/*** 返回摇号结果* @return 0:中签   1:没中* @throws Exception*/@Overridepublic Integer call() throws Exception {Random random = new Random();//模拟摇号,10天内出结果TimeUnit.SECONDS.sleep(random.nextInt(10));int result = random.nextInt(2);System.out.println("     "+Thread.currentThread().getName()+" is done!");return result;}}public static void main(String[] args) throws InterruptedException, ExecutionException {Yaohao gangxu1 = new Yaohao();Yaohao gangxu2 = new Yaohao();Yaohao gangxu3 = new Yaohao();Yaohao gangxu4 = new Yaohao();ExecutorService es = Executors.newCachedThreadPool();Future<Integer> result1 = es.submit(gangxu1);Future<Integer> result2 = es.submit(gangxu2);Future<Integer> result3 = es.submit(gangxu3);Future<Integer> result4 = es.submit(gangxu4);es.shutdown();System.out.println("刚需1,摇号结果:"+(result1.get()==1?"中签":"没中"));System.out.println("刚需2,摇号结果:"+(result2.get()==1?"中签":"没中"));System.out.println("刚需3,摇号结果:"+(result3.get()==1?"中签":"没中"));System.out.println("刚需4,摇号结果:"+(result4.get()==1?"中签":"没中"));}}

CompletableFuture的用法

  1. 创建异步操作,runAsync(不支持返回值) 和 supplyAsync方法(支持返回值)
  2. 计算结果完成时的回调方法
       whenComplete:执行完当前任务的线程,继续执行 whenComplete 的任务。
       whenCompleteAsync: 执行完当前任务的线程,把whenCompleteAsync 的任务继续提交给线程池来执行。
       exceptionally:当前任务出现异常时,执行exceptionally中的回调方法。
  3. thenApply 方法,当一个线程依赖另一个线程时,可以使用 thenApply 方法来把这两个线程串行化。
  4. handle 方法
    handle 是执行任务完成时对结果的处理。
    handle 方法和 thenApply 方法处理方式基本一样。不同的是 handle 是在任务完成后再执行,还可以处理异常的任务。thenApply 只可以执行正常的任务,任务出现异常则不执行 thenApply 方法。
  5. thenAccept 消费处理结果,接收任务的处理结果,并消费处理,无返回结果。
  6. thenRun 方法,跟 thenAccept 方法不一样的是,不关心任务的处理结果。只要上面的任务执行完成,就开始执行 thenAccept 。
  7. thenCombine 合并任务,thenCombine 会把 两个 CompletionStage 的任务都执行完成后,把两个任务的结果一块交给 thenCombine 来处理。
  8. thenCompose 方法,thenCompose 方法允许你对两个 CompletionStage 进行流水线操作,第一个操作完成时,将其结果作为参数传递给第二个操作。

实际的例子可以参考下面这篇文章,写得很简单明了。
https://www.jianshu.com/p/6bac52527ca4

Future和CompletableFuture的区别

Future在Java5就引入了。

优点:一定程度上让一个线程池内的任务异步执行了
缺点:传统回调最大的问题就是不能将控制流分离到不同的事件处理器中。例如主线程等待各个异步执行的线程返回的结果来做下一步操作,则必须阻塞在future.get()的地方等待结果返回。这时候又变成同步了。

CompletableFuture在Java8引入。

实现了Future和CompletionStage接口,保留了Future的优点,并且弥补了其不足。即异步的任务完成后,需要用其结果继续操作时,无需等待。可以直接通过thenAccept、thenApply、thenCompose等方式将前面异步处理的结果交给另外一个异步事件处理线程来处理。
可见,这种方式才是我们需要的异步处理。一个控制流的多个异步事件处理能无缝的连接在一起。

Future和CompletableFuture的用法和区别相关推荐

  1. python 类变量、实例变量、参数、实例方法、类方法、静态方法 的用法和区别

    #!/usr/bin/env python # -*- encoding: utf-8 -*- """ @Introduce : 类变量.实例变量.参数.实例方法.类方法 ...

  2. kmalloc/kfree,vmalloc/vfree函数用法和区别

    kmalloc/kfree,vmalloc/vfree函数用法和区别 1.kmalloc 1>kmalloc内存分配和malloc相似,除非被阻塞否则他执行的速度非常快,而且不对获得空间清零. ...

  3. Javascript:history.go()和history.back()的用法和区别

    Javascript:history.go()和history.back()的用法和区别  简单的说就是:go(-1): 返回上一页,原页面表单中的内容会丢失:back(): 返回上一页,原页表表单中 ...

  4. set和enum类型的用法和区别

    mysql中的set和enum类型的用法和区别 mysql中的enum和set其实都是string类型的而且只能在指定的集合里取值, 不同的是set可以取多个值,enum只能取一个值.   1 2 3 ...

  5. 多线程创建方式 线程池、Future和CompletableFuture

    大家好,我是烤鸭: 今天说一下 多线程的几种创建方式及使用. 1. Thread 和 Runnable 继承 Thread 类 和实现 Runnable 接口.     这种就不举例子了. 2.线程池 ...

  6. Flink的异步I/O及Future和CompletableFuture

    1 概述   Flink在做流数据计算时,经常要外部系统进行交互,如Redis.Hive.HBase等等存储系统.系统间通信延迟是否会拖慢整个Flink作业,影响整体吞吐量和实时性.   如需要查询外 ...

  7. PHP中MySQL、MySQLi和PDO的用法和区别

    MySQL 是 PHP 操作 MySQL 数据库最原始的 Extension.MySQLi 的 i 代表 Improvement ,提供了相对进阶的功能,就 Extension 而言,本身也增加了安全 ...

  8. Java-线程中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和区别

    Java线程中sleep().wait()和notify()和notifyAll().suspend和resume().yield().join().interrupt()的用法和区别 从操作系统的角 ...

  9. ASP.NET Application,Session,Cookie和ViewState等对象用法和区别

    ASP.NET Application,Session,Cookie和ViewState等对象用法和区别 在ASP.NET中,有很多种保存信息的内置对象,如:Application,Session,C ...

最新文章

  1. 用户认证-什么是认证
  2. 输入文字自动生成图片_批量生成变化的图片文字海报
  3. ad怎么修改栅格_江苏宋女士回农村100万盖洋房,6个闺蜜结伴养老,你怎么看?...
  4. JQuery动态增加删除元素
  5. 关于Redis热点key的一些思考
  6. php和java环境整合
  7. C语言初学必练100道
  8. p6spy mysql8_P6Spy配置使用
  9. arcgis for android 调用公网天地图注记重影问题
  10. python枚举详解
  11. unity帧动画事件多次播放
  12. 一个WinForm程序的生与死
  13. 区块链安全:实现公链双花攻击的多种方法
  14. 干货!CDN内容分发网络实战技巧
  15. 社群裂变工具有哪些?怎么用?微信如何引流客源呢?
  16. CSS基础之 背景属性设置
  17. Android的手势操作(Gesture)
  18. 微信视频号服务商怎么赚钱?
  19. WebStorm右端小地图/代码收缩图
  20. 火山小视频伪原创方法 视频文件分割改变md5

热门文章

  1. Kafka可靠性分析
  2. WIN10+GTX1050+CUDA9.0+VS2013+caffe
  3. 【电信学】【2004】MIMO系统的天线设计
  4. 0基础、其他行业转行,适合学Python吗?
  5. Python从视频文件中提取音频
  6. 如何修改Word文档里面的显示比例
  7. 关于机器人若干重要现实问题的思考
  8. 如何将jpg转换成PDF转换器教程
  9. pandas 多条件筛选DataFrame
  10. Brocade MLX/MLXe/XMR 系列交换机接口板一直 interactive 无法 up 的解决办法