【问题标题】:Why does the future hang in the interpreter?为什么未来挂在口译员身上?
【发布时间】:2016-10-30 00:05:07
【问题描述】:

以下单行代码挂在 Scala REPL 中

import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.{Future, future, Await}
import scala.concurrent.duration._

def fib(n: Int): Int = {println(n + " is handeled by " + Thread.currentThread.getName) ; if (n < 2) n else Await.result( Future.sequence(List(1,2) map (i => Future{println(n-i); n-i} map fib)) map (_.sum), Duration.Inf)} ; fib(3)

它的核心是

val lf: List[Future[Int]] = List(1,2) map (i => Future{n-i} map fib)
val f: Future[List[Int]] = Future.sequence(lf)
Await.result(f, Inf)

它还挂在菊石解释器中。它更先进,允许中断执行,可能堆栈跟踪会告诉你一些事情

def fib(n: Int): Int = {println(n + " is handeled by " + Thread.currentThread.getName) ; if (n < 2) n else Await.result( Future.sequence(List(1,2) map (i => Future{println(n-i); n-i} map fib)) map (_.sum), Duration.Inf)} ; fib(3) 
3 is handeled by main
1
2
^C
Interrupted!
java.lang.NoClassDefFoundError: Could not initialize class ammonite.session.cmd3$
        at ammonite.session.cmd3$$anonfun$fib$1$$anonfun$apply$2.apply$mcII$sp(cmd3.scala:1)
        at ammonite.session.cmd3$$anonfun$fib$1$$anonfun$apply$2.apply(cmd3.scala:1)
        at ammonite.session.cmd3$$anonfun$fib$1$$anonfun$apply$2.apply(cmd3.scala:1)
        at scala.util.Success$$anonfun$map$1.apply(Try.scala:237)
        at scala.util.Try$.apply(Try.scala:192)
        at scala.util.Success.map(Try.scala:237)
        at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:237)
        at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:237)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
        at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
        at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1253)
        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1346)
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
java.lang.NoClassDefFoundError: Could not initialize class ammonite.session.cmd3$
        at ammonite.session.cmd3$$anonfun$fib$1$$anonfun$apply$2.apply$mcII$sp(cmd3.scala:1)
        at ammonite.session.cmd3$$anonfun$fib$1$$anonfun$apply$2.apply(cmd3.scala:1)
        at ammonite.session.cmd3$$anonfun$fib$1$$anonfun$apply$2.apply(cmd3.scala:1)
        at scala.util.Success$$anonfun$map$1.apply(Try.scala:237)
        at scala.util.Try$.apply(Try.scala:192)
        at scala.util.Success.map(Try.scala:237)
        at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:237)
        at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:237)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
        at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
        at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
ubuntu-workspace@ 

如您所见,代码显示 n=3 is handeled by main,打印 1 和 2 并挂起。这意味着期货已经开始但尚未结束。他们没有按照地图的要求进行fib。我可以用Future{fib(n-i)} 替换Future{n-i} map fib,但没有任何变化。同时,代码在 Scastie 中正常进行。这表明行为很大程度上取决于上下文。

【问题讨论】:

  • 版主注意:请保持 cmets 文明和建设性 - 谢谢。

标签: multithreading scala future freeze


【解决方案1】:

这是一个关于在对象初始化器中启动线程的重复问题。

快速的解决方法是使用scala -Yrepl-class-based

相关问题:Scala: Parallel collection in object initializer causes a program to hang

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    • 2023-03-23
    • 2010-09-13
    • 1970-01-01
    相关资源
    最近更新 更多