Gauva使用ListenableFuture介绍说明

 更新时间:2023年01月09日 17:00:33   作者:鲲鹏飞九万里  
并发是一个困难问题,但是通过强大和强大的抽象能够显著的简化工作。为了简化问题,Gauva使用ListenableFuture扩展了JDK的Future接口,这篇文章主要介绍了Gauva使用ListenableFuture

一、ListenableFuture 介绍

并发是一个困难问题,但是通过强大和强大的抽象能够显著的简化工作。为了简化问题,Gauva使用ListenableFuture扩展了JDK的Future接口,

**我们强烈建议你在你所有的代码中使用ListenableFuture代替Future,**因为:

  • 大多数的Future方法需要它;
  • 这比以后更改为ListenableFuture更容易;
  • 实用方法的提供者不需要提供FutureListenableFuture方法的变体;

二、接口

传统的Future代表着异步计算的结果:一个计算可能也可能没有完成生成结果。Future可以是一个程序计算的句柄,一个来自服务的承诺提供给我们一个结果。

ListenableFuture允许你注册一个回调函数,一旦计算是完成或者计算是已经完成,回调函数会立马执行。这个简单的添加能有效的支持多种Future接口不支持的操作。

基础的操作被ListenableFuture添加是通过addListener(Runnable, Executor),它指定了当Future的计算完成之后,指定的Runnable将会在Executor中执行。

三、添加回调函数

大多数用户更喜欢使用Futures.addCallback(ListenableFuture, FutureCallback, Executor),一个FutueCallback有两个方法:

  • onSuccess(V) 如果future执行成功,基于结果进行执行。
  • onFailure(Throwable) 如果future执行失败,基于失败进行执行。

四、创建

相对于JDKExecutorService.submit(Callable) 方法初始化一个异步的计算。Guava提供了一个ListeningExecutorService 接口,它能在任何ExecutorService返回一个正常Future的地方,返回一个ListenableFuture。为了将ExecutorService转换成ListeningExecutorService ,仅需要使用MoreExecutors.listeningDecorator(executorService)

        ListeningExecutorService service =
                MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(
                  Runtime.getRuntime().availableProcessors()));
        ListenableFuture<String> listenableFuture = service.submit(() -> callDemo());
        Futures.addCallback(listenableFuture, new FutureCallback<String>() {
            @Override
            public void onSuccess(String result) {
                System.out.println("Run Ok : " + result);
//                service.shutdown();
            }
            @Override
            public void onFailure(Throwable t) {
                System.out.println("Run Fail: " + t);
            }
        }, service);

或者,如果你从一个基于FutureTask的API进行转换,Guava提供了ListenableFutureTask.create(Callable)ListenableFutureTask.create(Runnable, V) 。并不像JDK,ListenableFutureTask并不意味着直接扩展。

如果您更喜欢设置未来值的抽象而不是实现计算值的方法,请考虑扩展 AbstractFuture<V> 或直接使用 SettableFuture

如果你必须将另一个API提供的Future转换成ListenableFuture,你没有选择除了使用重量级的JdkFutureAdapters.listenInPoolThread(Future) ,将Future转化成ListenableFuture。无论什么时候,只要有可能,都应该修改源代码去返回一个ListenableFuture

五、应用

使用ListenableFuture的重要原因是,它让异步的链操作成为可能。

很多有效的其它操作使用ListenableFuture是支持的,而单独使用Future是不支持的。不同的操作能够被不同的Executor执行,并且单个 ListenableFuture 可以有多个等待它的操作。

当多个操作应该在另一个操作开始时立即开始时——“扇出”——ListenableFuture 才起作用:它触发所有请求的回调。通过稍微多一点的工作,我们能“扇入”,或触发ListenableFuture进行计算只要若干个其它的Future执行完(看:Futures.allAsList)。

方法描述延伸
Futures.transformAsync(ListenableFuture, AsyncFunction, Executor)返回一个新的ListenableFuture,它的结果是应用AsyncFunction。AsyncFunction是对ListenableFuture结果的加工
Futures.transform(ListenableFuture, Function, Executor)返回一个新的ListenableFuture,它的结果是应用Function。Function是对ListenableFuture结果的加工
Futures.allAsList(Iterable<ListenableFuture<V>>)返回一个ListenableFuture,它的值是一个list包含了每一个输入输入future的值。如果任何的future失败或取消,这个future也失败或取消。
Futures.successfulAsList(Iterable<ListenableFuture>)返回一个ListenableFuture,它的值是一个list包含了每一个输入输入future的值。如果相对应的future失败或取消,将用null代替。

一个AsyncFunction 提供了一个方法ListenableFuture<B> apply(A a)。它用于异步传输一个值。

六、避免内嵌的Future

ListenableFuture<ListenableFuture<String>> nestedFuture =
                executorService.submit(() -> otherExecutorService.submit(() -> callDemo())); 

上面的代码是不正确的, 因为如果外部Future的取消与外部Future的完成竞争,则该取消不会传播到内部Future。 使用 get() 或侦 听器检查其他Future的失败也是一个常见错误,但除非特别注意,否则从 otherCallable 抛出的异常将被抑制。

为了避免这种情况,Guava 的所有Future处理方法(以及一些来自 JDK)都有 *Async 版本,可以安全地解开这个嵌套:

  • Futures.transformAsync(ListenableFuture, AsyncFunction, Executor)
  • ExecutorService.submit(Callable)
  • Futures.submitAsync(AsyncCallable, Executor)

到此这篇关于Gauva使用ListenableFuture介绍说明的文章就介绍到这了,更多相关Gauva ListenableFuture内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中Buffer缓冲区的ByteBuffer类详解

    Java中Buffer缓冲区的ByteBuffer类详解

    这篇文章主要介绍了Java中Buffer缓冲区的ByteBuffer类详解,ByteBuffer类是Java NIO库中的一个重要类,用于处理字节数据,它提供了一种灵活的方式来读取、写入和操作字节数据,ByteBuffer类是一个抽象类,可以通过静态方法创建不同类型的ByteBuffer对象,需要的朋友可以参考下
    2023-10-10
  • Spring自动装配bean的方式总结

    Spring自动装配bean的方式总结

    这篇主要介绍了Spring自动装配Bean的方式总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2024-01-01
  • Java未赋值变量的初始值解析(默认值)

    Java未赋值变量的初始值解析(默认值)

    这篇文章主要介绍了Java未赋值变量的初始值(默认值),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • SpringMVC中的HandlerMappingIntrospector工具类详解

    SpringMVC中的HandlerMappingIntrospector工具类详解

    这篇文章主要介绍了SpringMVC中的HandlerMappingIntrospector工具类详解,这是一个Spring MVC助手类,用于集合应用所配置的HandlerMapping(url pattern和请求处理handler之间的映射)表,用于获取针对某个请求的如下信息,需要的朋友可以参考下
    2023-12-12
  • Java Optional用法面试题精讲

    Java Optional用法面试题精讲

    这篇文章主要为大家介绍了Java Optional用法面试题精讲,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • JAVA获取Image的三种方式

    JAVA获取Image的三种方式

    这篇文章主要介绍了JAVA获取Image的三种方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java原生HttpClient的使用详解

    Java原生HttpClient的使用详解

    Java开发语言中实现HTTP请求的方法主要有两种:一种是JAVA的标准类HttpUrlConnection,比较原生的实现方法;另一种是第三方开源框架HTTPClient。本文就将详细讲讲Java中原生HttpClient的使用,需要的可以参考一下
    2022-04-04
  • IDEA SpringBoot:Cannot resolve configuration property配置文件问题

    IDEA SpringBoot:Cannot resolve configuration&

    这篇文章主要介绍了IDEA SpringBoot:Cannot resolve configuration property配置文件问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java+swing+Mysql实现商品销售管理系统

    Java+swing+Mysql实现商品销售管理系统

    基础扎不扎实只有在实战中才能显现,本篇文章手把手带你用Java+swing+Mysql实现商品销售管理系统,大家可以在过程中查缺补漏,提升水平
    2022-01-01
  • Springboot实现多线程及线程池监控

    Springboot实现多线程及线程池监控

    线程池的监控很重要,本文就来介绍一下Springboot实现多线程及线程池监控,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-01-01

最新评论