文章目录

    • 创建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...10future1 is not done and future2 is not donefuture1 is not done and future2 is not donefuture1 is not done and future2 is not donefuture1 is not done and future2 is not doneCalculating...100future1 is done and future2 is not donefuture1 is done and future2 is not donefuture1 is done and future2 is not done100 and 10000

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

calculating...10calculating...100future1 is not done and future2 is not donefuture1 is not done and future2 is not donefuture1 is not done and future2 is not donefuture1 is not done and future2 is not done100 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的博客

©著作权归作者所有:来自51CTO博客作者ddean2009的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. java中FutureTask的使用
  2. 在java中使用JMH(Java Microbenchmark Harness)做性能测试
  3. java并发中CountDownLatch的使用
  4. MySQL 语句分析的神器-Optimizer Trace
  5. 控制流程系列教材 (三)- java的while语句
  6. 杀软对抗:一个面向***工程师的杀软绕过思路分享(含实现代码)
  7. 基数反馈(Cardinality Feedback)
  8. WORKAREA_SIZE_POLICY参数引起的ORA-04030错误
  9. 11gR2 新特性--待定的统计信息(Pending Statistic)

随机推荐

  1. android中比较两张图片的相似度
  2. Adding prebuilt shared library to Andr
  3. android 启动报错
  4. android 日历组件(CalendarView)
  5. 2019博客汇总
  6. System Permissions—— android系统权限
  7. PC和Android(安卓)adb通信
  8. linaro pandaboard android 编译kernel
  9. 手把手叫你用android 调研web services
  10. 【Android 基础7.1 7.2】AsyncTask & Asy