假设我有一个未来的结果,我们把它叫做 garfield
def garfield = Future{
Thread.sleep(100)
System.currentTimeMillis()
}
我可以跑 garfield
同时 for comprehension
这样
val f1 = garfield
val f2 = garfield
for {
r1 <- f1
r2 <- f2
} yield r1 -> r2
如上所述 这个 的答案。
假设我不想用未来的变量污染局部作用域,如果我以后不需要它们。这是一个有效的替代方法吗?
for {
f1 <- Future{garfield}
f2 <- Future{garfield}
r1 <- f1
r2 <- f2
} yield r1 -> r2
看来我原来的方法,使用 Future.apply
包括开销,大部分时间会导致顺序执行,见 例子.
使用替代方法
for {
f1 <- Future.successful(garfield)
f2 <- Future.successful(garfield)
r1 <- f1
r2 <- f2
} yield r1 -> r2
的表现符合预期。
话又说回来,这种方法有点奇怪,也许更传统的方法是在期货的范围内,在一个 Unit
是首选。
val res = {
val f1 = garfield
val f2 = garfield
for {
r1 <- f1
r2 <- f2
} yield r1 -> r2
}
我很好奇,是否有人能再说明一下零星没有并发执行的原因。
For comprehension在本质上是顺序的,所以不,这行不通。
你的代码将依次评估f1和f2。
下面的代码应该是可行的
(更新了一些变化,从 联系 来自@ViktorKlang )
object FutureFor extends App {
import concurrent.ExecutionContext.Implicits.global
for {
_ <- Future.unit
f1 = Future { "garfield" }
f2 = Future { "garfield" }
r1 <- f1
r2 <- f2
} yield r1 -> r2
}
你必须从 <-
从 "初始 "的未来消耗,它将决定结果类型的理解。
并发将实现与 =
因为它将创造期货,然后用它们来消费。<-
但这真的很混乱,我建议坚持使用
val f1 = garfield
val f2 = garfield
for {
r1 <- f1
r2 <- f2
} yield r1 -> r2
编辑。
你的方法 Future { garfield() }
确实有效,我忽略了一点,它是包装一个未来。
而且它是并发的。请看修改后的代码来证明这一点。
import java.time.Instant
import java.util.concurrent.Executors
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Random
object FutureFor extends App {
private val random = new Random()
implicit val ex =
ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))
def garfield() = Future {
val started = Instant.now()
Thread.sleep(random.nextInt(1000))
val stopped = Instant.now()
s"Started:$started on ${Thread.currentThread().getName}. Stopped $stopped"
}
val bar = Future
.sequence {
for {
_ <- 1 to 10
} yield
for {
f1 <- Future { garfield() }
f2 <- Future { garfield() }
r1 <- f1
r2 <- f2
} yield r1 + "\n" + r2
}
.map(_.mkString("\n\n"))
.foreach(println)
Thread.sleep(5000)
}
Prints:
Started:2020-04-24T13:23:46.043230Z on pool-1-thread-3. Stopped 2020-04-24T13:23:46.889296Z
Started:2020-04-24T13:23:46.428162Z on pool-1-thread-10. Stopped 2020-04-24T13:23:47.159586Z
....