当前位置: 首页 > 知识库问答 >
问题:

爪哇相当于斯卡拉的未来?

公羊信厚
2023-03-14

我在Java寻找与斯卡拉的未来相当的东西。

我正在寻找一种构造类型,它允许我将任务(Runnables/Callables)提交到我选择的特定线程池,返回futures,允许我在任务完成时将一些逻辑(以非阻塞方式)链接到它。大概是这样的:

var executor = Executors.newCachedThreadPool();
executor.submit(() -> {
  Thread.sleep(5000);
  return 666;
}.onComplete(v -> System.out.println(v));

Java的线程池(通过Executorssingleton提供)似乎总是返回标准的JavaFutures,它只允许我调用阻塞get()。另一方面,据我所知,CompletableFuture,更类似于Scala的promise,并且不绑定到线程池。

Java提供我想要的东西吗?Java人如何处理这种操作?

共有1个答案

任飞鸣
2023-03-14

你想要回地狱吗?那是新的。

据我所知,它更类似于Scala的promise,并且不绑定到线程池。

不准确的我认为完整的未来正是你想要的:)

有一个默认的执行器将被使用,但是如果您愿意,您也可以显式地指定一个执行器,supplyAsyncrunAsync方法具有重载,您可以在其中传递显式的执行器,并且链中的所有内容都使用将来您要链接的任何用途。

CompletableFuture.supplyAsync(() -> {
    Thread.sleep(5000);
    System.out.println("Helloooo there, from stage 1!");
    return 666;
}).whenCompleteAsync((result, exception) -> {
    Thread.sleep(5000);
    System.out.println("Coming to you live from stage 2: " + result);
    // result is null if an error has occurred in stage 1.
    // exception is null if an error did not occur.
});

注意:如果你把它扔进一个psv主,请确保添加一个。get()在最末尾;如果没有这一点,虚拟机将在未来真正开始工作之前退出。然后,您将看到:

> Helloooo there, from stage 1!
> Coming to you live from stage 2: 666

约5秒后出现第一个字符串。10之后的第二个,然后VM退出。

注意,看起来java的未来不是未来。java中的未来会遇到回调地狱,并且无法解决“红/蓝”方法问题(这就是调用(可能)阻止异步代码的任何东西是一个非常有问题的bug的问题:很难静态检测,几乎不可能进行测试,但会完全破坏您在生产中的性能。不幸的是,很难意识到您意外地做了一些阻塞的事情,并且很少有现有的API和库都记录了它们是否这样做,然后promise在不考虑更改向后不兼容的更新并适当地管理它们的版本以反映这一点的情况下永远不会更改它们)。

这些都是可以解决的问题,但这并不容易:Java将需要“异步”或类似的功能,还需要认真地添加文档,可能还需要一些可以在编译时检查的功能,例如使用注释。

但这些都不在java未来的任何地方。然而,即将出现的是“ProjectLowe”,它将轻量级线程(“光纤”)添加到java中:它们代表执行状态,但本身不能在另一个核心上运行。你可以制造数百万个em,没问题。然后你就写:

int priceyOp1 = doSomethingThatTakesLong();
int priceyOp2 = thisIsAlsoSlow(priceyOp1);

把整个东西塞进光纤中,甚至有一个漏斗概念,线程池将意识到它当前运行的光纤现在被阻塞,然后从池中捞出另一个光纤并运行一段时间。这并不意味着期货完全没有意义,但这可能意味着期货将保持利基,异步/回调地狱不会很快解决。

 类似资料:
  • 我正在尝试编写一个程序来实现对埃拉托西的筛选。我可以从2到任何给定的结束编号,但我们正在处理的赋值要求我们输入起始值。我完全被卡住了。我试过很多不同的代码,但它总是给我奇怪的答案。 我的起点是起始值,终点是结束值。我基本上想找到这个范围的素数。谢谢!!!

  • 基本上,我在cassandra上运行两个期货查询,然后我需要做一些计算并返回值(值的平均值)。 这是我的代码: 那么问题出在哪里呢? skus.foreach 在 ListBuffer 中追加结果值。由于一切都是异步的,当我尝试在我的主数据库中获取结果时,我得到了一个错误,说我不能被零除。 事实上,由于我的Sku.findSkusByProduct返回一个Future,当我尝试计算平均值时,卷是空

  • 我试图用我的gradle项目运行junit测试,但不管是什么测试,它们都会抛出以下堆栈跟踪 我已经看到了一些建议的解决方案,但似乎没有一个奏效。当我在ant中运行它们时,我的测试运行良好。我已经确保xerces使用的是最新版本,我还添加了建议的版本 对于JVM,但似乎什么都不起作用。 任何建议都将不胜感激。我可以根据要求提供更多信息。 **更新** 做了以下更改- 但现在的结果如图所示 **更新2

  • 我在mac os X 10.6.8上安装了詹金斯,成功安装詹金斯后,我在浏览器中以默认地址浏览它http://localhost:8080但tomcat页面显示的不是詹金斯主页。我读了jenkins的文档,它将需要执行命令java-jarjenkins.war--http pPort=8080 当执行命令java-jarjenkins时。war——httpPort=8080 有这个错误 2016-

  • 我正在围绕java库编写一个小的scala包装器。 Java库有一个对象QueryExecutor,它公开了2种方法: 执行(查询):结果 asyncExecute(查询):ListenableFuture[结果] 本文中的ListenableFuture是来自guava图书馆的。 我希望我的scala包装器返回一个Future[Result]而不是java对象,但我不确定实现它的最佳方法是什么。

  • 请看下面的代码,让我知道我哪里做错了? 使用: DSE版本-5.1.0 172.31.16.45:9042连接到测试群集。[cqlsh 5.0.1|Cassandra3.10.0.1652|DSE 5.1.0|CQL规范3.4.4|本地协议v4]使用HELP寻求帮助。 谢谢 斯卡拉 斯卡拉 斯卡拉 我在这里什么都得不到?甚至没有错误。