文章目录

  • 创建Future
  • 从Future获取结果
  • 取消Future
  • 多线程环境中运行

java中Future的使用

Future是java 1.5引入的一个interface,可以方便的用于异步结果的获取。 本文将会通过具体的例子讲解如何使用Future。

创建Future

正如上面所说,Future代表的是异步执行的结果,意思是当异步执行结束之后,返回的结果将会保存在Future中。

那么我们什么时候会用到Future呢? 一般来说,当我们执行一个长时间运行的任务时,使用Future就可以让我们暂时去处理其他的任务,等长任务执行完毕再返回其结果。

经常会使用到Future的场景有:1. 计算密集场景。2. 处理大数据量。3. 远程方法调用等。

接下来我们将会使用ExecutorService来创建一个Future。

    <T> Future<T> submit(Callable<T> task);

上面是ExecutorService中定义的一个submit方法,它接收一个Callable参数,并返回一个Future。

我们用一个线程来计算一个平方运算:

    private ExecutorService executor= Executors.newSingleThreadExecutor();public Future<Integer> calculate(Integer input) {return executor.submit(() -> {System.out.println("Calculating..."+ input);Thread.sleep(1000);return input * input;});}

submit需要接受一个Callable参数,Callable需要实现一个call方法,并返回结果。这里我们使用lamaba表达式来简化这一个流程。

从Future获取结果

上面我们创建好了Future,接下来我们看一下怎么获取到Future的值。

       FutureUsage futureUsage=new FutureUsage();Future<Integer> futureOne = futureUsage.calculate(20);while(!futureOne.isDone()) {System.out.println("Calculating...");Thread.sleep(300);}Integer result = futureOne.get();

首先我们通过Future.isDone() 来判断这个异步操作是否执行完毕,如果完毕我们就可以直接调用futureOne.get()来获得Futre的结果。

这里futureOne.get()是一个阻塞操作,会一直等待异步执行完毕才返回结果。

如果我们不想等待,future提供了一个带时间的方法:

Integer result = futureOne.get(500, TimeUnit.MILLISECONDS);

如果在等待时间结束的时候,Future还有返回,则会抛出一个TimeoutException。

取消Future

如果我们提交了一个异步程序,但是想取消它, 则可以这样:

uture<Integer> futureTwo = futureUsage.calculate(4);boolean canceled = futureTwo.cancel(true);

Future.cancel(boolean) 传入一个boolean参数,来选择是否中断正在运行的task。

如果我们cancel之后,再次调用get()方法,则会抛出CancellationException。

多线程环境中运行

如果有两个计算任务,先看下在单线程下运行的结果。

        Future<Integer> future1 = futureUsage.calculate(10);Future<Integer> future2 = futureUsage.calculate(100);while (!(future1.isDone() && future2.isDone())) {System.out.println(String.format("future1 is %s and future2 is %s",future1.isDone() ? "done" : "not done",future2.isDone() ? "done" : "not done"));Thread.sleep(300);}Integer result1 = future1.get();Integer result2 = future2.get();System.out.println(result1 + " and " + result2);

因为我们通过Executors.newSingleThreadExecutor()来创建的单线程池。所以运行结果如下:

Calculating...10
future1 is not done and future2 is not done
future1 is not done and future2 is not done
future1 is not done and future2 is not done
future1 is not done and future2 is not done
Calculating...100
future1 is done and future2 is not done
future1 is done and future2 is not done
future1 is done and future2 is not done
100 and 10000

如果我们使用Executors.newFixedThreadPool(2)来创建一个多线程池,则可以得到如下的结果:

calculating...10
calculating...100
future1 is not done and future2 is not done
future1 is not done and future2 is not done
future1 is not done and future2 is not done
future1 is not done and future2 is not done
100 and 10000

本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/future

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

更多教程请参考 flydean的博客

java中Future的使用相关推荐

  1. Java中的Runnable、Callable、Future、FutureTask

    Java中存在Runnable.Callable.Future.FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别. ...

  2. java中 immutable,future,nio

    什么是Future? 用过Java并发包的朋友或许对Future (interface) 已经比较熟悉了,其实Future 本身是一种被广泛运用的并发设计模式,可在很大程度上简化需要数据流同步的并发应 ...

  3. Java中的Runnable、Callable、Future、FutureTask的区别与示例

    原文地址:http://blog.csdn.net/bboyfeiyu/article/details/24851847 --------------------------------------- ...

  4. Java中Callable和Future

    Java中为什么需要Callable 在java中有两种创建线程的方法: 一种是继承Thread类,重写run方法: public class TestMain {public static void ...

  5. 面试官:你知道Java中的回调机制吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:22j.co/cFPf          正文    调用和 ...

  6. 面试:你知道Java中的回调机制吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | 带妳心菲 来源 | cnblogs.com/prayjo ...

  7. 面试:你知道 Java 中的回调机制吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | 带妳心菲 来源 | cnblogs.com/prayjo ...

  8. Java中的等待/通知机制(wait/notify)

    为什么80%的码农都做不了架构师?>>>    当一个线程修改了一个对象的值,另外一个线程需要感知到这个变化,并且做出相应的操作时,可以使用Java中的等待/通知机制去实现这个功能. ...

  9. Java中实现多线程关键词整理

    Java中的Runable,Callable,Future,FutureTask,ExecutorService,Excetor,Excutors,ThreadPoolExcetor在这里对这些关键词 ...

最新文章

  1. dis的前缀单词有哪些_英语单词词根.词缀II 5个最高频英语前缀 必背
  2. 文字转语音,语音转语音,实际的转化过程
  3. wota dance
  4. github 运行python_Github Actions教程:运行python代码并Push到远端仓库
  5. app中html静态页面缓存,移动端index.html被缓存问题
  6. WPF Datagrid合并表头的思路
  7. @async方法不调用了_在Spring中使用Future对象调用Async方法调用
  8. mysql数据库安装教程32位,看这一篇就够了!
  9. JRebel 启动报错 could not be processed by xxx
  10. 23个.net开源项目
  11. 小米Android OS特别高,干翻小米,最强定制安卓系统诞生?Color OS11表现如何
  12. 网络安全实验室 脚本关 解析
  13. 在网站中使用VideoJs视频播放器播放视频
  14. 电脑出现无法访问您试图使用的功能所在的网络位置问题的解决方式
  15. windows 进程监控 Procmon.exe
  16. ACM-ICPC国际大学生程序设计竞赛亚洲区大连赛区(2016)地区赛——花开花落终有时
  17. 直流无刷电机驱动芯片DRV8306使用
  18. 简单方法解决火狐浏览器主页被篡改/挟持,主页变成垃圾网站的问题
  19. 120年奥运历史数据分析
  20. SQLmap在进行SQL注入时的整个流程

热门文章

  1. Python3了,你还在用%和format格式化输出吗
  2. 决策树之C4.5算法
  3. QEMU 构建系统架构
  4. 什么是缓存?为什么要使用Redis?
  5. 数据结构与算法 | 斐波那契查找
  6. LeetCode解题的常见模式套路
  7. 五分钟快速理解 Reactor 模型
  8. 为什么 Java 中 2*(i*i) 比 2*i*i 更快?
  9. 设计模式:备忘录模式(Memento)
  10. 分布式链路跟踪中的 traceid 和 spanid 代表什么?