【问题标题】:how to convert java Future<V> to guava ListenableFuture<V>如何将 java Future<V> 转换为 guava ListenableFuture<V>
【发布时间】:2023-03-31 15:13:01
【问题描述】:

我需要找到一种方法将 Future 转换为 ListenableFuture。 目前我正在使用一个返回 Future 的服务,但我需要连接一个监听器。 我无法更改服务接口,因为它不属于我。

有没有简单的方法来做到这一点?

我已经阅读了番石榴文档,但我仍然找不到方法。

【问题讨论】:

  • 你的Future来自哪里?是来自ExecutorService吗?
  • 如果有一种不用创建自己的线程的好方法来做到这一点,我会感到惊讶; ListenableFutureFuture 更强大。
  • @Will my Future 来自cloud.google.com/appengine/docs/java/javadoc/com/google/…。我找不到更好的方法来从 gae/j 异步获取 url。

标签: java concurrency guava futuretask


【解决方案1】:

Future 只是 get 接口,而 Guava ListenableFuture 是 Future 接口,注册的 Runnable 监听器在 set 或 setException 时由 complete() 运行(由 guava AbstractFuture 实现)。

import com.google.common.util.concurrent.AbstractFuture;
import java.util.concurrent.Future;

public class ListenerFuture<V> extends AbstractFuture<V> {

    public ListenerFuture(Future<V> future){
        this.future= future;
    }
    // blocking in future get, then run listener in AbstractFuture set
    public void fireListener(){
        try {
            super.set(future.get());
        }catch (Exception e){
            throw new RuntimeException("guava set ListenableFuture", e);
        }
    }

    private Future<V> future;
}

ListenerFuture<V> response= new ListenerFuture(service.response());
response.addListener(Runnable, Executor);
// pass the ListenableFuture to whom need it
// do something else until who must have service response call the blocking
response.fileListner()

Guava AbstractFuture 有其局限性:

  1. Listener 是列表,但通常只使用 1 个 - 矫枉过正。如果需要多个侦听器,请将其分叉到您的侦听器中或使用消息传递来考虑您的设计。
  2. setException 将返回值设置为Exception,所以用户必须在get()时使用instanceof来区分Exception与否
  3. 在 Future 管道中,层数过多的 addListener() 使代码难以阅读。

我更喜欢 CompletableFuture.supply().thenApply().thenAccept().handle()

【讨论】:

  • 问题指出“我无法更改服务接口,因为它不属于我”。所以他无法控制未来是如何被创造出来的。您的回答没有回答问题的内容。
  • 请在您的回答中提供更多详细信息。正如目前所写的那样,很难理解您的解决方案。
【解决方案2】:

Guava 为这种转换提供了 JdkFutureAdapters 类型。 API 状态

使用提供纯文本的库所需的实用程序 未来的实例。

例如

Future<?> future = ...;
ListenableFuture<?> listenable = JdkFutureAdapters.listenInPoolThread(future);

但你应该小心使用它:当你已经提交任务时,很难模拟可听的未来,因为没有办法在那里完成挂钩,所以 Guava 采用一个新线程并阻塞在那里,直到原始 Future 完成。

Guava Wiki 也是 contains some information on this specific case

【讨论】:

  • @qwwdfsad 好的。我没看到。我会试一试的。
猜你喜欢
  • 2019-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-23
  • 2013-04-13
  • 1970-01-01
  • 1970-01-01
  • 2016-05-04
相关资源
最近更新 更多