加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 直接从CompletableFuture.thenAccept返回值

发布时间:2020-12-15 04:38:23 所属栏目:Java 来源:网络整理
导读:我试图从CompletableFuture返回一个列表,如下所示: public ListProvider get() { CompletableFutureListProvider providersResponse = getSomeData(); return providersResponse.thenAccept((ListProvider providers) - { return providers; });} 它失败了
我试图从CompletableFuture返回一个列表,如下所示:

public List<Provider> get() {
    CompletableFuture<List<Provider>> providersResponse = getSomeData();
    return providersResponse.thenAccept((List<Provider> providers) -> {
        return providers;
    });
}

它失败了“意外的返回类型.但是如何以异步方式返回结果?

解决方法

你的目标存在根本矛盾.您只能使用get()返回完整的,可直接使用的列表或“以异步方式返回结果”.

如果方法List< Provider> get()应该返回一个List,它可以被调用者无限制地使用,它不能保持异步操作,因为当get()返回时操作必须已经完成.这可以像调用join()一样简单,等待完成并获得结果:

public List<Provider> get() {
    CompletableFuture<List<Provider>> providersResponse = getSomeData();
    return providersResponse.join();
}

要不就

public List<Provider> get() {
    return getSomeData().join();
}

这有效地将getSomeData()的潜在异步操作转换为同步操作.

This answer,使用

public List<Provider> get() {
    List<Provider> providers = new ArrayList<>();
    CompletableFuture<List<Provider>> providersResponse = getSomeData();
    providersResponse.thenAccept(providers::addAll);
    return providers;
}

不等待操作完成,但在调度addAll操作后返回一个新的ArrayList,该操作的执行完全不受此方法的控制.

这是一个异步操作,因此当get()返回时,List可能仍然是空的,但稍后会被任意线程更新.由于ArrayList不是线程安全的,因此感知状态不必是,空的或完成的,它可以是任意的中间状态,甚至不需要是一致的.在使用该代码时,要为奇怪的异常,看起来不可能的情况或其他惊喜做好准备.

当您通过使用线程安全List实现来修复该代码时,仍然会遇到以下问题:返回的List在查询时可能为空,并在调用者控件之外的任意时间点填充.这是不可修复的,如开头所说,这是想要异步操作但返回List的基本问题.

CompletableFuture已经是潜在异步操作的封装,因此如果您希望操作保持异步,只需返回CompletableFuture< List< Provider>>给来电者,以便获得控制权.否则,如果您希望调用者接收可以无限制使用的List,请在返回结果之前等待完成,例如通过join().

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读