我正在ExecutionContext
为我的基于期货的代码使用自定义,这样每当用户决定中断程序时,无论正在发生的任何并发活动都会在他们第一次尝试安排另一个Future
要处理的活动时被中断,并且程序可以退出,而不是等待任何长时间运行的任务完成。
但是,Executor.shutdownNow
调用会导致 ajava.lang.InterruptedException
来自 first sleep(500)
,但它永远不会到达 the Await.result
and 因此也不会到达catch
orfinally
块;此外,该程序只是无限期挂起。
import scala.concurrent._
import scala.concurrent.forkjoin.ForkJoinPool
object test extends App {
val executor = new ForkJoinPool
implicit val execCtx: ExecutionContext = ExecutionContext.fromExecutor(executor)
try {
Await.result(
for {
_ <- future { blocking { println(1); Thread.sleep(500); println(2) } }
_ = executor.shutdownNow
_ <- future { blocking { println(3); Thread.sleep(500); println(4) } }
} yield (),
duration.Duration.Inf)
} catch { case _: InterruptedException =>
println("CATCH") // not reached
} finally {
println("FINAL") // not reached
executor.shutdown
}
}
runMain test
运行时(如果重要,使用 SBT ),这是输出:
1
shutting down[error] (ForkJoinPool-1-worker-13) java.lang.InterruptedException: sleep interrupted
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(test.scala:20)
at test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(test.scala:20)
at test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(test.scala:20)
at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
at scala.concurrent.package$.blocking(package.scala:50)
at test$$anonfun$1.apply$mcV$sp(test.scala:20)
at test$$anonfun$1.apply(test.scala:20)
at test$$anonfun$1.apply(test.scala:20)
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)
为什么会这样?