浅谈javafuture接口

     2022-04-23     734

关键词:

Java项目编程中,为了充分利用计算机CPU资源,一般开启多个线程来执行异步任务。但不管是继承Thread类还是实现Runnable接口,都无法获取任务执行的结果。JDK 5中引入了Callable和Future,通过它们执行异步任务可以获取执行结果。
FutureTask分析

JDK 5中获取任务执行的结果主要是通过FutureTask类实现的。FutureTask实现了RunnableFuture的接口,它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。一般结合线程池ExecutorService类使用,大致流程如下: 1. 调用线程将callable任务submit到线程池,返回Future对象 2. 任务被封装成FutureTask对象
<ignore_js_op>技术分享图片 

      执行线程调用FutureTask的run方法,run主要逻辑是执行Callable任务的call方法获取结果,并将结果赋值给全局变量outcome调用线程调用Future对象的get方法来获取任务执行的结果


上述步骤4中,如果任务没有执行完成,调用get方法时,调用线程将被阻塞直到任务完成。
假设这样的一个场景,向Executor批量提交了A、B两个任务,A任务耗时20ms,B任务耗时10ms,每个任务完成后就能根据结果继续做后面的事。在该场景中,B任务先完成A任务后完成,由于调用线程不知道哪个任务会先完成,只能按照任务的提交顺序调用get方法阻塞获取结果,最后要耗时20ms才会继续做A、B任务后面的事。
显然这种情况下用Future机制是不合适的,B任务先完成了却增加了额外的等待时间。这个问题的原因是Future没有提供好的方法去判断第一个完成的任务。当然你可以通过Future提供的isDone方法轮询的去判断第一个完成的任务,但会消耗无谓的CPU资源。
从上面的分析可以看到,单使用Future是不方便的,其主要原因有:一方面没有提供方法去判断第一个完成的任务;另一方面是 Future没有提供Callback机制,只能通过阻塞的get方法去获取结果。针对第一个问题,JAVA引入了CompletionService接口。
CompletionService分析

CompletionService整合了Executor和BlockingQueue的功能。CompletionService维护一个保存Future对象的BlockingQueue。只有当这个Future对象状态是结束的时候,才会加入到这个Queue中。这样就确保执行时间较短的任务率先被存入队列中。与Future流程的不同主要是: 1. callable任务提交后,exexute方法执行的是封装成QueueingFuture的任务对象。QueueingFuture是FutureTask的子类,重写了done方法,在task执行完成之后将当前future添加到阻塞队列completionQueue
<ignore_js_op>技术分享图片 

      获取结果是通过CompletionService的take方法和poll方法,这两个方法都委托给了BlockingQueue,它会在结果不可用时阻塞


<ignore_js_op>技术分享图片 


由实现可知,Future的回调行为是在ExecutorCompletionService中实现的,完成的任务会封装到一个队列中,供客户端询问时使用。Future本身是没有提供回调方法的。另外,使用CompletionService虽然能保证任务结果按照完成先后顺序排序,但仍存在调用阻塞的问题。Guava的ListenableFuture 和JDK8的CompletableFuture对Future进行了扩展,当计算结果完成后可以立即执行后续逻辑。
Future的扩展

Guava的ListenableFuture扩展了Future接口,是一个可以监听结果的Future。就是它可以监听异步执行的过程,执行完了,自动触发后续操作。常用的添加监听器的方法是Futures.addCallback方法,大致流程如下: 1.  每当对一个ListenableFuture增加回调时,都会向线程池提交监听任务callbackListener。该任务的run方法会通过getDone方法阻塞获取future的执行结果。代码片段见下:
<ignore_js_op>技术分享图片 

      获取结果后立即执行callback的onFailure方法或者onSuccess方法,不会阻塞调用


当然ListenableFuture的回调机制不是通用的,如果主任务异步执行子任务并且需等待返回结果,此时ListenableFuture的作用和Future几乎差不多,都是通过get方法阻塞获取结果。如果主任务不需要等待子任务的返回结果,但子任务一旦计算完成就做其他计算,此时使用ListenableFuture非常合适。
CompletableFuture是JDK1.8新增的的类,提供了非常强大的Future的扩展功能。可以对多个异步处理进行编排,实现更复杂的异步处理。它能够将回调放到与任务不同的线程中执行,也能将回调作为继续执行的同步函数,在与任务相同的线程中执行。大家可以参考CompletableFuture的API了解它提供的功能。
总结

在实际项目中,需要根据具体的业务场景选择合适的Future工具类来实现异步编程。如果项目中使用Java 8,推荐使用CompletableFuture类,它提供了更多的异步控制。如果使用之前版本,可以使用Guava等框架提供的Future工具类。

from: https://www.wengbi.com/thread_69744_1.html


























不会用javafuture,我怀疑你泡茶没我快,又是超长图文!!

你有一个思想,我有一个思想,我们交换后,一个人就有两个思想IfyoucanNOTexplainitsimply,youdoNOTunderstanditwellenough现陆续将Demo代码和技术文章整理在一起Github实践精选,方便大家阅读查看,本文同样收录在此,觉得不错,还请Star前... 查看详情

javafuture模式

1/*2*Tochangethislicenseheader,chooseLicenseHeadersinProjectProperties.3*Tochangethistemplatefile,chooseTools|Templates4*andopenthetemplateintheeditor.5*/67/**8*9*@authorlx10*/1112importjava.util.conc 查看详情

javafuture如何强制终止

future.cancel(true);一定能结束futrue线程吗?参考技术Afuture咱写的。 查看详情

javafuture模式实现

JavaFuture模式简介Future模式是Java多线程常用的模式,而且JDK也内置对Future模式的支持,比如在java.util.concurrent包下的FutureTask类。其核心思想在于:发出请求后,可以立即返回对象,但是这个对象实际上是个假对象,并不可立即使... 查看详情

浅谈接口

接口:先看下面一段话:       如果,你即将准备开始编程,就是那种感觉需要很多很多类,而其中有些类,你已经提前知道需要哪些共同的功能。怎么办?当然首先想到,提前给他们规定好一种模式,规定他们是什么... 查看详情

浅谈接口

接口:先看下面一段话:       如果,你即将准备开始编程,就是那种感觉需要很多很多类,而其中有些类,你已经提前知道需要哪些共同的功能。怎么办?当然首先想到,提前给他们规定好一种模式,规定他们是什么... 查看详情

[原创]浅谈互联网金融接口测试平台搭建

[原创]浅谈互联网金融接口测试平台搭建  接口测试我想各位做测试都不陌生,尤其是在现在分层测试思想倡导下,接口测试可以说是互联网行业必备的测试技能之一,我以前的博文也有讲过类似的内容,要想了解可以移驾到... 查看详情

浅谈java接口

一、接口的本质探讨    官方解释:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的... 查看详情

从javafuture到guavalistenablefuture实现异步调用

原文地址:http://blog.csdn.net/pistolove/article/details/51232004JavaFuture????通过Executors可以创建不同类似的线程池,常见的大概有下表几种类型,还有些可能为被列出。在实际应用中,个人感觉主要使用newCachedThreadPook和newFixedThreadPool来创... 查看详情

浅谈接口测试

一、接口测试的必要性和意义这里主要说说接口测试的必要性和意义:接口测试实施在多系统的平台架构下,有着极为高效的成本收益比(当然,单元测试收益更高,但实施单元测试的成本投入更大,技术要求更高,所以应该选... 查看详情

javafuture源码分析

JDKfuture框架,提供了一种异步编程模式,基于线程池的。将任务runnable/callable提交到线程池executor,返回一个Future对象。通过future.get()获取执行结果,这里提交到线程池,后面的操作不会阻塞。future.get()获取结果会阻塞,其实也... 查看详情

从javafuture到guavalistenablefuture实现异步调用

从Javafuture到GuavaListenableFuture实现异步调用置顶 2016年04月24日09:11:14 皮斯特劳沃 阅读数:17570 标签: java异步调用线程非阻塞更多个人分类: 多线程异步调用总结 版权声明:本文为博主原创文章,未经... 查看详情

浅谈接口diff测试

浅谈接口Diff测试转自:https://mp.weixin.qq.com/s/6H-AGaqpwf47gcxs2Sw9fQ所有的手工CASE和自动化CASE都跑了,上线为啥还经常有问题呢? 服务端语言由PHP语言改成GO了,原来的接口逻辑我又不了解,怎么测试? 测试环境测的好好的,... 查看详情

浅谈java中的autocloseable接口

接口AutoCloseable是jdk1.7出现的新接口,存在于java.lang包中,可配合jdk1.7出现的try-with-resources新语法特性一起使用,用于自动关闭某个系统资源,如:文件,网络等。该接口只定义了一个方法:void close()throws Exception具体的... 查看详情

浅谈java中的autocloseable接口

接口AutoCloseable是jdk1.7出现的新接口,存在于java.lang包中,可配合jdk1.7出现的try-with-resources新语法特性一起使用,用于自动关闭某个系统资源,如:文件,网络等。该接口只定义了一个方法:void close()throws Exception具体的... 查看详情

性能基础之浅谈常见接口性能压测

背景随着主流系统的服务化设计,特别是SOA架构和微服务架构的流行,接口已经成为各系统间通信的桥梁。所以,接口的性能压测也变得越来越重要。SOA(ServerOrientedArchitecture,面向服务架构)是目前通用的组件模型。它将软件系... 查看详情

浅谈接口自动化测试

(转自:https://www.cnblogs.com/imyalost/p/7430126.html)昨晚在某个测试交流群,听了一个测试老司机分享接口自动化测试的内容,对接口自动化有了更深的一些认识,也为接下来公司的接口自动化实施,提供了更多的思路。这篇博客,... 查看详情

javafuture函数的作用

finalFuture<?>future=executor.submit(newRunnable()在并发编程时,一般使用runnable,然后扔给线程池完事,这种情况下不需要线程的结果。所以run的返回值是void类型。如果是一个多线程协作程序,比如菲波拉切数列,1,1,2,3,5,8...... 查看详情