Scala future 基础知识

标签 scala asynchronous concurrency promise future

我在 Scala 中有以下代码:

case class Water(temp: Int)

case class Milk(temp: Int)

def heatWaterFor(minutes: Int, water: Water) = Future {
  Thread.sleep(1000)
  Water(82)
}

def boilMilkFor(minutes: Int, milk: Milk) = Future {
  Thread.sleep(1000)
  Milk(90)
}

def frothMilk(hotwater: Water, hotmilk: Milk) = Future {
  Thread.sleep(1000)
  hotmilk
}

val start = System.currentTimeMillis()

val milkMaker = for {
   water <- heatWaterFor(10, Water(10))
   milk <- boilMilkFor(5, Milk(10))
   frothed = frothMilk(water, milk)
   hotMilk <- frothed
 } yield (hotMilk)

Await.ready(milkMaker, Duration.Inf)
val end = System.currentTimeMillis() - start
println(milkMaker.value + " , Time taken: "+((end/1000))+" seconds.")

我的目的是并行化 heatWaterFor(...)boilMilkFor(...)因为他们是独立的。但我觉得上面的代码是连续的,根本没有利用 future 的力量。显然,运行需要 3000 毫秒(这是一个额外的证明)。

我在这里缺少的基本东西是什么?

最佳答案

A for 表达式简化为一系列 map , flatMapwithFilter操作。你的特定表达被简化为这样的:

heatWaterFor(10, Water(10))
        .flatMap(water => boilMilkFor(5, Milk(10))
                             .flatMap(milk => frothMilk(water, milk))

正如你在这里看到的,下一个 future 的执行是在上一个完成时开始的。因此,如果要并行执行它们,则需要执行以下操作:
val heatWater = heatWaterFor(10, Water(10))
val boilMilk = boilMilkFor(5, Milk(10))

val milkMaker = for {
   water <- heatWater
   milk <- boilMilk
   hotMilk <- frothMilk(water, milk)
} yield (hotMilk)

这将开始 heatWaterForboilMilkFor同时,然后开始 frothMilk当这两个都完成时(因为它取决于其他两个 future 的结果)。

关于Scala future 基础知识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32242979/

相关文章:

scala - 无法使用 case 类从 Row 的 RDD 创建数据框

scala - Spark Bucketizer - 即使没有元素也显示所有桶

C++:Boost::asio:WAITING同一函数中的异步处理程序

java - 如何将矩阵的不同行传递给 threadPool。 [ JAVA ]

java - 防止由特定触发器触发的实例的并发执行

database - 处理非重叠范围的建议方法(例如调度)

scala - 使用 Slick 为 java.time.LocalDate 创建自定义列映射

scala - 无法使用 Mesos 运行 Spark

ios - 使用带有完成 block 的自定义运算符

c# - 如何在不阻塞主 UI 线程的情况下等待事件处理程序的返回值