Scala 在程序终止之前,期货不会运行
我试图在新的Scala 2.10上重现这个示例。 我使用的代码是:Scala 在程序终止之前,期货不会运行,scala,concurrency,future,Scala,Concurrency,Future,我试图在新的Scala 2.10上重现这个示例。 我使用的代码是: import scala.concurrent.Future import scala.concurrent.future object Test { def main(args: Array[String]) { println("Test print before future") val s = "Hello" val f = future {s + " future!"}
import scala.concurrent.Future
import scala.concurrent.future
object Test {
def main(args: Array[String]) {
println("Test print before future")
val s = "Hello"
val f = future {s + " future!"}
f onSuccess {case v => println(v)}
println("Test print after future")
}
}
代替打印:
Test print before future
Hello future!
Test print after future
它只是打印:
Test print before future
Test print after future
知道我为什么有这种行为吗?我的scala编译器版本是2.10.0-20120507。我认为这里的问题是计时。很可能您未来的代码是在单独的deamon线程中运行的。我认为应用程序完成得非常快,这个deamon线程没有足够的时间来正确执行(应用程序不会等待deamon线程完成)。但这也是非常依赖于系统的行为。对我来说,它打印:
Test print before future
Test print after future
Hello future!
然后退出(我使用的是Scala 2.10.0-M3)。为了测试它,您可以尝试以下操作-只需将主执行线程置于睡眠状态几秒钟,然后查看Hello future代码>已打印:
import scala.concurrent.Future
import scala.concurrent.future
object Test {
def main(args: Array[String]) {
println("Test print before future")
val s = "Hello"
val f = future {s + " future!"}
f onSuccess {case v => println(v)}
println("Test print after future")
Thread.sleep(3000)
println("Test print at the end.")
}
}
问题是,您正在以独立程序的形式执行它,其主线程在其中一个工作线程执行“Hello future!”println
之前终止。(新的futures库生成的线程是守护进程线程)
您还可以使用wait
对象(也在scala.concurrent
中)等待,直到将来的f
完成:
import scala.concurrent._
import scala.concurrent.util._
object Test {
def main(args: Array[String]) {
println("Test print before future")
val s = "Hello"
val f = future {s + " future!"}
f onSuccess {case v => println(v)}
println("Test print after future")
Await.ready(f, Duration.Inf)
}
}
这可以打印:
Test print before future
Test print after future
Hello future!
或者,它可以根据线程计划在“以后测试打印”之前打印“Hello future!”
同样,您可以强制主线程在最后一个println
之前等待f
完成,如下所示:
import scala.concurrent._
import scala.concurrent.util._
object Test {
def main(args: Array[String]) {
println("Test print before future")
val s = "Hello"
val f = future {s + " future!"}
f onSuccess {case v => println(v)}
Await.ready(f, Duration.Inf)
println("Test print after future")
}
}
将打印:
Test print before future
Hello future!
Test print after future
但是,请注意,当您使用wait
时,您正在阻塞。当然,这对于确保主应用程序线程不终止是有意义的,但除非另有必要,否则通常不应使用
(对于此类情况,Await
对象是一个必要的转义图案填充,但是在整个应用程序代码中使用它而不考虑其语义可能会导致执行速度较慢、并行性较差。例如,如果需要确保回调按某个指定的顺序执行,则还有其他替代方法,例如和en
和map
方法在Future
)我只想补充一点,一般来说,期货没有运行的另一种可能性是:达到线程池限制
在你的情况下,它可能只是一个时间问题,正如其他人指出的,但作为未来的参考,考虑这个例子:
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
object FutureDebug {
def main( args: Array[String] ) {
for (i <- Range(0, 4)) {
future {
while (true) {
Thread.sleep(1000)
println("I'm doing stupid things in a future")
}
}
}
println("(1) reached? yes")
val fut = future {
for (i <- Range(0, 1000)) {
println("never reached " + i)
}
3.14
}
println("(2) reached? yes")
Await.result(fut, Duration.Inf)
println("(3) reached? no")
}
}
导入scala.concurrent_
导入scala.concurrent.ExecutionContext.Implicits.global
导入scala.concurrent.duration.duration
对象未来调试{
def main(参数:数组[字符串]){
例如(我知道吗?我考虑过这一点,因为在处理goroutines时,go中的情况与goroutines完全相同:在关闭主块之前,您使用通道等待goroutines发送的消息。@Heather是否可以等待一个以上的未来?@AjOnFire晚了6年,但是的,future.sequence()
将一系列的未来变成一个单一的未来,你可以等待它
@CervEd我妈妈总是说迟做总比不做好。谢谢你的更新!