我在 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
, flatMap
和 withFilter
操作。你的特定表达被简化为这样的:
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)
这将开始
heatWaterFor
和 boilMilkFor
同时,然后开始 frothMilk
当这两个都完成时(因为它取决于其他两个 future 的结果)。
关于Scala future 基础知识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32242979/