为什么Await.result(f, t)
将重新抛出由f引发的异常,而它不会重新抛出致命错误?
是错误还是预期行为?
以下REPL序列再现了行为:
scala> import scala.concurrent.duration._
import scala.concurrent.duration._
scala> import scala.concurrent._
import scala.concurrent._
scala> val ec = scala.concurrent.ExecutionContext.global
ec: scala.concurrent.ExecutionContextExecutor = scala.concurrent.impl.ExecutionContextImpl@2d2217da
scala> Await.result(Future{throw new RuntimeException()}(ec), Duration.Inf)
java.lang.RuntimeException
at $anonfun$1.apply(<console>:15)
at $anonfun$1.apply(<console>:15)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at scala.concurrent.impl.ExecutionContextImpl$$anon$3.exec(ExecutionContextImpl.scala:107)
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)
scala> Await.result(Future{throw new LinkageError()}(ec), Duration.Inf)
scala.NotImplementedError: an implementation is missing
at $line28.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$1.apply(<console>:15)
at $line28.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$1.apply(<console>:15)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at scala.concurrent.impl.ExecutionContextImpl$$anon$3.exec(ExecutionContextImpl.scala:107)
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)
(hanging - needs ctrl-c)
两次执行之间的区别在于第一次执行将终止执行,第二次将打印堆栈跟踪然后挂起,永远等待(虽然不确定)。
Edit1:将NotImplementedError
替换为LinkageError
,因为在{2.1}中修改了NotImplementedError
行为,而LinkageError
保持不变。
Edit2:添加&#34;致命&#34;描述问题中的错误。
答案 0 :(得分:1)
这是因为scala.util.NonFatal
(在Future
的实现中使用)与NotImplementedError
不匹配,导致它被视为致命的。在2.11中,这已经改变了,NotImplementedError
不再是致命的。请参阅this commit。