【译】Scale 期货-并发处理

135 阅读3分钟

期货让我们在主线程之外运行值并处理背景,或者尚未由mappin运行值...

期货允许我们在主线程之外运行值,并通过与回调映射它们来处理在后台运行或尚未执行的值。

如果您来自Java背景,您可能会知道java.util.concurrent.Future。使用此方法存在几个挑战:

  1. 检索值时始终会阻塞线程。
  2. 计算完成的等待时间。
  3. GET方法是检索值的唯一方法。

这 是编写并发代码的一种疲惫和敌对的方式。

我们在Scala拥有更好的Future Scala.concurrent.Future。使用Scala Futures,我们可以实现:

  1. 实时无阻塞计算。
  2. onComplete(成功/失败)的回调,即Future中的值是Try子句的实例。
  3. 多个期货的映射。

期货本质上是不可变的,并在内部进行缓存。一旦指定了值或例外,就无法修改/覆盖期货(很难实现参照透明性)。

简单的例子:

执行上下文

可以将其ExecutionContext视为分配新线程或使用池/当前线程(不推荐)执行Future及其功能的管理员。不导入ExecutionContext范围,我们就无法执行未来。

ExecutionContext在许多情况下,使用Global可以避免创建自定义项的需要ExecutionContext。默认全局变量ExecutionContext将并行度级别设置为可用处理器的数量(可以增加)。

回呼

期货最终返回需要由回调处理的值。 未处理的值/异常将丢失。

期货有您可以使用的方法。常见的回调方法有:

  • onCompleteFuture中的回调值是该Try子句的实例:

onSuccessonFailure已弃用。您可以使用filterforeachmap,还有更多-了解这里

等待

此方法仅在需要阻塞线程的系统中使用。通常不建议这样做,因为它会影响性能。

Await.result 将阻塞主线程,并等待结果指定的持续时间。

上面的代码将仅显示:

img

这需要持续时间导入几秒钟。为了处理并发应用程序中的时间,Scala具有:

这种支持不同的时间单位: toNanostoMicrostoMillistoSecondstoMinutestoHourstoDays,和toUnit(unit: TimeUnit)

对于庞大的代码,回调并不总是最好的方法。Scala期货可以与一起使用for (enumerators) yield e,其中enumerators指的是用分号分隔的列表。枚举器可以是引入新变量的生成器,也可以是过滤器。

很高兴知道

例外情况

当异步计算引发未处理的异常时,与这些计算关联的Future将失败。失败的期货存储实例Throwable而不是结果值。Future提供了failed投影方法,该方法可以Throwable将视为另一个的成功值Future

投影

为了让我们理解作为例外返回的结果,期货也有预测。如果原始的Future失败,则failed投影将返回包含type值的Future Throwable。如果原始的Future成功,则failed投影将失败,并带有NoSuchElementException

完整的代码

输出量

在使主线程等待两秒钟之后,我们可以看到来自Future线程的输出,如下所示:

img

结论

期货是一种以高效且无阻塞的方式运行并行程序的好方法。我们可以使用外部库(scalaz,cat等)以更实用的方式实现此目的。

Akka是基于Scala构建的参与者模型库,并提供了一种实现长时间运行的并行流程(克服Scala Futures的局限性)的方法。期货在使用Scala构建的其他框架中使用,例如Play框架,lagom,Apache Spark等。

请查看我们的页面YolkOrbit, 以获取有关Scala和Akka的更多信息。

感谢您的阅读和支持。

主题:

scala, 函数式编程, 分布式计算, 并发, 并行编程, java

原文链接:dzone.com/articles/sc…